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

Subversion Repositories ethmac

[/] [ethmac/] [trunk/] [bench/] [verilog/] [eth_phy.v] - Blame information for rev 191

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 169 mohor
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  File name: eth_phy.v                                        ////
4
////                                                              ////
5 170 mohor
////  This file is part of the Ethernet IP core project           ////
6 169 mohor
////  http://www.opencores.org/projects/ethmac/                   ////
7
////                                                              ////
8
////  Author(s):                                                  ////
9
////      - Tadej Markovic, tadej@opencores.org                   ////
10
////                                                              ////
11
////  All additional information is available in the README.txt   ////
12
////  file.                                                       ////
13
////                                                              ////
14
//////////////////////////////////////////////////////////////////////
15
////                                                              ////
16 170 mohor
//// Copyright (C) 2002  Authors                                  ////
17 169 mohor
////                                                              ////
18
//// This source file may be used and distributed without         ////
19
//// restriction provided that this copyright statement is not    ////
20
//// removed from the file and that any derivative work contains  ////
21
//// the original copyright notice and the associated disclaimer. ////
22
////                                                              ////
23
//// This source file is free software; you can redistribute it   ////
24
//// and/or modify it under the terms of the GNU Lesser General   ////
25
//// Public License as published by the Free Software Foundation; ////
26
//// either version 2.1 of the License, or (at your option) any   ////
27
//// later version.                                               ////
28
////                                                              ////
29
//// This source is distributed in the hope that it will be       ////
30
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
31
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
32
//// PURPOSE.  See the GNU Lesser General Public License for more ////
33
//// details.                                                     ////
34
////                                                              ////
35
//// You should have received a copy of the GNU Lesser General    ////
36
//// Public License along with this source; if not, download it   ////
37
//// from http://www.opencores.org/lgpl.shtml                     ////
38
////                                                              ////
39
//////////////////////////////////////////////////////////////////////
40
//
41
// CVS Revision History
42
//
43
// $Log: not supported by cvs2svn $
44 188 tadej
// Revision 1.3  2002/09/13 14:50:15  mohor
45
// Bug in MIIM fixed.
46
//
47 177 mohor
// Revision 1.2  2002/09/13 12:29:14  mohor
48
// Headers changed.
49
//
50 170 mohor
// Revision 1.1  2002/09/13 11:57:20  mohor
51
// New testbench. Thanks to Tadej M - "The Spammer".
52 169 mohor
//
53
//
54 170 mohor
//
55 169 mohor
 
56
`include "timescale.v"
57
`include "eth_phy_defines.v"
58
`include "tb_eth_defines.v"
59
module eth_phy // This PHY model simulate simplified Intel LXT971A PHY
60
(
61
        // COMMON
62
        m_rst_n_i,
63
 
64
        // MAC TX
65
        mtx_clk_o,
66
        mtxd_i,
67
        mtxen_i,
68
        mtxerr_i,
69
 
70
        // MAC RX
71
        mrx_clk_o,
72
        mrxd_o,
73
        mrxdv_o,
74
        mrxerr_o,
75
 
76
        mcoll_o,
77
        mcrs_o,
78
 
79
        // MIIM
80
        mdc_i,
81
        md_io,
82
 
83
        // SYSTEM
84
        phy_log
85
);
86
 
87
//////////////////////////////////////////////////////////////////////
88
//
89
// Input/output signals
90
//
91
//////////////////////////////////////////////////////////////////////
92
 
93
// MAC miscellaneous signals
94
input           m_rst_n_i;
95
// MAC TX signals
96
output          mtx_clk_o;
97
input   [3:0]   mtxd_i;
98
input           mtxen_i;
99
input           mtxerr_i;
100
// MAC RX signals
101
output          mrx_clk_o;
102
output  [3:0]   mrxd_o;
103
output          mrxdv_o;
104
output          mrxerr_o;
105
// MAC common signals
106
output          mcoll_o;
107
output          mcrs_o;
108
// MAC management signals
109
input           mdc_i;
110
inout           md_io;
111
// SYSTEM
112
input   [31:0]  phy_log;
113
 
114
 
115
//////////////////////////////////////////////////////////////////////
116
//
117
// PHY management (MIIM) REGISTER definitions
118
//
119
//////////////////////////////////////////////////////////////////////
120
//
121
//   Supported registers:
122
//
123
// Addr | Register Name
124
//--------------------------------------------------------------------
125
//   0  | Control reg.     |
126
//   1  | Status reg. #1   |--> normal operation
127
//   2  | PHY ID reg. 1    |
128
//   3  | PHY ID reg. 2    |
129
//----------------------
130
// Addr | Data MEMORY      |-->  for testing
131
//
132
//--------------------------------------------------------------------
133
//
134
// Control register
135
reg            control_bit15; // self clearing bit
136
reg    [14:10] control_bit14_10;
137
reg            control_bit9; // self clearing bit
138
reg    [8:0]   control_bit8_0;
139
// Status register
140
wire   [15:9]  status_bit15_9 = `SUPPORTED_SPEED_AND_PORT;
141
wire           status_bit8    = `EXTENDED_STATUS;
142
wire           status_bit7    = 1'b0; // reserved
143
reg    [6:0]   status_bit6_0;
144
// PHY ID register 1
145
wire   [15:0]  phy_id1        = `PHY_ID1;
146
// PHY ID register 2
147
wire   [15:0]  phy_id2        = {`PHY_ID2, `MAN_MODEL_NUM, `MAN_REVISION_NUM};
148
//--------------------------------------------------------------------
149
//
150
// Data MEMORY
151
reg    [15:0]  data_mem [0:31]; // 32 locations of 16-bit data width
152
//
153
//////////////////////////////////////////////////////////////////////
154
 
155
 
156
//////////////////////////////////////////////////////////////////////
157
//
158
// PHY clocks - RX & TX
159
//
160
//////////////////////////////////////////////////////////////////////
161
 
162
reg       mtx_clk_o;
163
reg       mrx_clk_o;
164
 
165
// random generator for a RX period when link is down
166
real      rx_link_down_halfperiod;
167
 
168
always@(status_bit6_0[2])
169
begin
170
  if (!status_bit6_0[2]) // Link is down
171
  begin
172
    #1 rx_link_down_halfperiod = ({$random} % 243) + 13;
173
    `ifdef VERBOSE
174
    #1 $fdisplay(phy_log, "   (%0t)(%m)MAC RX clock is %f MHz while ethernet link is down!",
175
                 $time, (1000/(rx_link_down_halfperiod*2)) );
176
    `endif
177
  end
178
end
179
 
180
`ifdef VERBOSE
181
always@(status_bit6_0[2])
182
begin
183
  if (!status_bit6_0[2]) // Link is down
184
    #1 $fdisplay(phy_log, "   (%0t)(%m)Ethernet link is down!", $time);
185
  else
186
    #1 $fdisplay(phy_log, "   (%0t)(%m)Ethernet link is up!", $time);
187
end
188
`endif
189
 
190
// speed selection signal eth_speed: 1'b1 - 100 Mbps, 1'b0 - 10 Mbps
191
wire      eth_speed;
192
 
193
assign eth_speed = ( (control_bit14_10[13]) && !((`LED_CFG1) && (`LED_CFG2)) );
194
 
195
`ifdef VERBOSE
196
always@(eth_speed)
197
begin
198
  if (eth_speed)
199
    #1 $fdisplay(phy_log, "   (%0t)(%m)PHY configured to 100 Mbps!", $time);
200
  else
201
    #1 $fdisplay(phy_log, "   (%0t)(%m)PHY configured tp 10 Mbps!", $time);
202
end
203
`endif
204
 
205
// different clock calculation between RX and TX, so that there is alsways a litle difference
206
always
207
begin
208
  mtx_clk_o = 0;
209
  #7;
210
  forever
211
  begin
212
    if (eth_speed) // 100 Mbps - 25 MHz, 40 ns
213
    begin
214
      #20 mtx_clk_o = ~mtx_clk_o;
215
    end
216
    else // 10 Mbps - 2.5 MHz, 400 ns
217
    begin
218
      #200 mtx_clk_o = ~mtx_clk_o;
219
    end
220
  end
221
end
222
 
223
always
224
begin
225
  mrx_clk_o = 1;
226
  #3;
227
  forever
228
  begin
229
    if (status_bit6_0[2]) // Link is UP
230
    begin
231
      if (eth_speed) // 100 Mbps - 25 MHz, 40 ns
232
      begin
233
        //#(((1/0.025001)/2)) 
234
        #19.99 mrx_clk_o = ~mrx_clk_o; // period is calculated from frequency in GHz
235
      end
236
      else // 10 Mbps - 2.5 MHz, 400 ns
237
      begin
238
        //#(((1/0.0024999)/2)) 
239
        #200.01 mrx_clk_o = ~mrx_clk_o; // period is calculated from frequency in GHz
240
      end
241
    end
242
    else // Link is down
243
    begin
244
      #(rx_link_down_halfperiod) mrx_clk_o = ~mrx_clk_o; // random frequency between 2 MHz and 40 MHz
245
    end
246
  end
247
end
248
 
249
//////////////////////////////////////////////////////////////////////
250
//
251
// PHY management (MIIM) interface
252
//
253
//////////////////////////////////////////////////////////////////////
254
reg             respond_to_all_phy_addr; // PHY will respond to all phy addresses
255
reg             no_preamble; // PHY responds to frames without preamble
256
 
257
integer         md_transfer_cnt; // counter countes the value of whole data transfer
258
reg             md_transfer_cnt_reset; // for reseting the counter
259
reg             md_io_reg; // registered input
260
reg             md_io_output; // registered output
261
reg             md_io_rd_wr;  // op-code latched (read or write)
262
reg             md_io_enable; // output enable
263
reg     [4:0]   phy_address; // address of PHY device
264
reg     [4:0]   reg_address; // address of a register
265
reg             md_get_phy_address; // for shifting PHY address in
266
reg             md_get_reg_address; // for shifting register address in
267
reg     [15:0]  reg_data_in; // data to be written in a register
268
reg             md_get_reg_data_in; // for shifting data in
269
reg             md_put_reg_data_in; // for storing data into a selected register
270
reg     [15:0]  reg_data_out; // data to be read from a register
271
reg             md_put_reg_data_out; // for registering data from a selected register
272
 
273
wire    [15:0]  register_bus_in; // data bus to a selected register
274
reg     [15:0]  register_bus_out; // data bus from a selected register
275
 
276
initial
277
begin
278
  md_io_enable = 1'b0;
279
  respond_to_all_phy_addr = 1'b0;
280
  no_preamble = 1'b0;
281
end
282
 
283
// tristate output
284
assign #1 md_io = (m_rst_n_i && md_io_enable) ? md_io_output : 1'bz ;
285
 
286
// registering input
287
always@(posedge mdc_i or negedge m_rst_n_i)
288
begin
289
  if (!m_rst_n_i)
290
    md_io_reg <= #1 0;
291
  else
292
    md_io_reg <= #1 md_io;
293
end
294
 
295
// getting (shifting) PHY address, Register address and Data in
296
// putting Data out and shifting
297
always@(posedge mdc_i or negedge m_rst_n_i)
298
begin
299
  if (!m_rst_n_i)
300
  begin
301
    phy_address <= 0;
302
    reg_address <= 0;
303
    reg_data_in <= 0;
304
    reg_data_out <= 0;
305
    md_io_output <= 0;
306
  end
307
  else
308
  begin
309
    if (md_get_phy_address)
310
    begin
311
      phy_address[4:1] <= phy_address[3:0]; // correct address is `ETH_PHY_ADDR
312
      phy_address[0]   <= md_io;
313
    end
314
    if (md_get_reg_address)
315
    begin
316
      reg_address[4:1] <= reg_address[3:0];
317
      reg_address[0]   <= md_io;
318
    end
319
    if (md_get_reg_data_in)
320
    begin
321
      reg_data_in[15:1] <= reg_data_in[14:0];
322
      reg_data_in[0]    <= md_io;
323
    end
324
    if (md_put_reg_data_out)
325
    begin
326
      reg_data_out <= register_bus_out;
327
    end
328
    if (md_io_enable)
329
    begin
330
      md_io_output       <= reg_data_out[15];
331
      reg_data_out[15:1] <= reg_data_out[14:0];
332
      reg_data_out[0]    <= 1'b0;
333
    end
334
  end
335
end
336
 
337
assign #1 register_bus_in = reg_data_in; // md_put_reg_data_in - allows writing to a selected register
338
 
339
// counter for transfer to and from MIIM
340
always@(posedge mdc_i or negedge m_rst_n_i)
341
begin
342
  if (!m_rst_n_i)
343
  begin
344
    if (no_preamble)
345
      md_transfer_cnt <= 33;
346
    else
347
      md_transfer_cnt <= 1;
348
  end
349
  else
350
  begin
351
    if (md_transfer_cnt_reset)
352
    begin
353
      if (no_preamble)
354
        md_transfer_cnt <= 33;
355
      else
356
        md_transfer_cnt <= 1;
357
    end
358
    else if (md_transfer_cnt < 64)
359
    begin
360
      md_transfer_cnt <= md_transfer_cnt + 1'b1;
361
    end
362
    else
363
    begin
364
      if (no_preamble)
365
        md_transfer_cnt <= 33;
366
      else
367
        md_transfer_cnt <= 1;
368
    end
369
  end
370
end
371
 
372
// MIIM transfer control
373
always@(m_rst_n_i or md_transfer_cnt or md_io_reg or md_io_rd_wr or
374
        phy_address or respond_to_all_phy_addr or no_preamble)
375
begin
376
  #1;
377
  while ((m_rst_n_i) && (md_transfer_cnt <= 64))
378
  begin
379
    // reset the signal - put registered data in the register (when write)
380
    // check preamble
381
    if (md_transfer_cnt < 33)
382
    begin
383
      #4 md_put_reg_data_in = 1'b0;
384
      if (md_io_reg !== 1'b1)
385
      begin
386
        #1 md_transfer_cnt_reset = 1'b1;
387
      end
388
      else
389
      begin
390
        #1 md_transfer_cnt_reset = 1'b0;
391
      end
392
    end
393
 
394
    // check start bits
395
    else if (md_transfer_cnt == 33)
396
    begin
397
      if (no_preamble)
398
      begin
399
        #4 md_put_reg_data_in = 1'b0;
400
        if (md_io_reg === 1'b0)
401
        begin
402
          #1 md_transfer_cnt_reset = 1'b0;
403
        end
404
        else
405
        begin
406
          #1 md_transfer_cnt_reset = 1'b1;
407
          //if ((md_io_reg !== 1'bz) && (md_io_reg !== 1'b1))
408
          if (md_io_reg !== 1'bz)
409
          begin
410
            // ERROR - start !
411
            `ifdef VERBOSE
412
            $fdisplay(phy_log, "*E (%0t)(%m)MIIM - wrong first start bit (without preamble)", $time);
413
            `endif
414
            #10 $stop;
415
          end
416
        end
417
      end
418
      else // with preamble
419
      begin
420 177 mohor
        #4 ;
421 169 mohor
        `ifdef VERBOSE
422 177 mohor
        $fdisplay(phy_log, "   (%0t)(%m)MIIM - 32-bit preamble received", $time);
423 169 mohor
        `endif
424 191 tadej
        // check start bit only if md_transfer_cnt_reset is inactive, because if
425
        // preamble suppression was changed start bit should not be checked
426
        if ((md_io_reg !== 1'b0) && (md_transfer_cnt_reset == 1'b0))
427 169 mohor
        begin
428
          // ERROR - start !
429
          `ifdef VERBOSE
430
          $fdisplay(phy_log, "*E (%0t)(%m)MIIM - wrong first start bit", $time);
431
          `endif
432
          #10 $stop;
433
        end
434
      end
435
    end
436
 
437
    else if (md_transfer_cnt == 34)
438
    begin
439
      #4;
440
      if (md_io_reg !== 1'b1)
441
      begin
442
        // ERROR - start !
443
        #1;
444
        `ifdef VERBOSE
445
        if (no_preamble)
446
          $fdisplay(phy_log, "*E (%0t)(%m)MIIM - wrong second start bit (without preamble)", $time);
447
        else
448
          $fdisplay(phy_log, "*E (%0t)(%m)MIIM - wrong second start bit", $time);
449
        `endif
450
        #10 $stop;
451
      end
452
      else
453
      begin
454
        `ifdef VERBOSE
455
        if (no_preamble)
456
          #1 $fdisplay(phy_log, "   (%0t)(%m)MIIM - 2 start bits received (without preamble)", $time);
457
        else
458
          #1 $fdisplay(phy_log, "   (%0t)(%m)MIIM - 2 start bits received", $time);
459
        `endif
460
      end
461
    end
462
 
463
    // register the op-code (rd / wr)
464
    else if (md_transfer_cnt == 35)
465
    begin
466
      #4;
467
      if (md_io_reg === 1'b1)
468
      begin
469
        #1 md_io_rd_wr = 1'b1;
470
      end
471
      else
472
      begin
473
        #1 md_io_rd_wr = 1'b0;
474
      end
475
    end
476
 
477
    else if (md_transfer_cnt == 36)
478
    begin
479
      #4;
480
      if ((md_io_reg === 1'b0) && (md_io_rd_wr == 1'b1))
481
      begin
482
        #1 md_io_rd_wr = 1'b1; // reading from PHY registers
483
        `ifdef VERBOSE
484
        $fdisplay(phy_log, "   (%0t)(%m)MIIM - op-code for READING from registers", $time);
485
        `endif
486
      end
487
      else if ((md_io_reg === 1'b1) && (md_io_rd_wr == 1'b0))
488
      begin
489
        #1 md_io_rd_wr = 1'b0; // writing to PHY registers
490
        `ifdef VERBOSE
491
        $fdisplay(phy_log, "   (%0t)(%m)MIIM - op-code for WRITING to registers", $time);
492
        `endif
493
      end
494
      else
495
      begin
496
        // ERROR - wrong opcode !
497
        `ifdef VERBOSE
498
        #1 $fdisplay(phy_log, "*E (%0t)(%m)MIIM - wrong OP-CODE", $time);
499
        `endif
500
        #10 $stop;
501
      end
502
    // set the signal - get PHY address
503
      begin
504
        #1 md_get_phy_address = 1'b1;
505
      end
506
    end
507
 
508
    // reset the signal - get PHY address
509
    else if (md_transfer_cnt == 41)
510
    begin
511
      #4 md_get_phy_address = 1'b0;
512
    // set the signal - get register address
513
      #1 md_get_reg_address = 1'b1;
514
    end
515
 
516
    // reset the signal - get register address
517
    // set the signal - put register data to output register
518
    else if (md_transfer_cnt == 46)
519
    begin
520
      #4 md_get_reg_address = 1'b0;
521
      #1 md_put_reg_data_out = 1'b1;
522
    end
523
 
524
    // reset the signal - put register data to output register
525
    // set the signal - enable md_io as output when read
526
    else if (md_transfer_cnt == 47)
527
    begin
528
      #4 md_put_reg_data_out = 1'b0;
529
      if (md_io_rd_wr) //read
530
      begin
531
        if (md_io_reg !== 1'bz)
532
        begin
533
          // ERROR - turn around !
534
          `ifdef VERBOSE
535
          #1 $fdisplay(phy_log, "*E (%0t)(%m)MIIM - wrong turn-around cycle before reading data out", $time);
536
          `endif
537
          #10 $stop;
538
        end
539
        if ((phy_address === `ETH_PHY_ADDR) || respond_to_all_phy_addr) // check the PHY address
540
        begin
541
          #1 md_io_enable = 1'b1;
542
          `ifdef VERBOSE
543
          $fdisplay(phy_log, "   (%0t)(%m)MIIM - received correct PHY ADDRESS: %x", $time, phy_address);
544
          `endif
545
        end
546
        else
547
        begin
548
          `ifdef VERBOSE
549
          #1 $fdisplay(phy_log, "*W (%0t)(%m)MIIM - received different PHY ADDRESS: %x", $time, phy_address);
550
          `endif
551
        end
552
      end
553
      else // write
554
      begin
555
        #1 md_io_enable = 1'b0;
556
    // check turn around cycle when write on clock 47
557
        if (md_io_reg !== 1'b1)
558
        begin
559
          // ERROR - turn around !
560
          `ifdef VERBOSE
561
          #1 $fdisplay(phy_log, "*E (%0t)(%m)MIIM - wrong 1. turn-around cycle before writing data in",
562
                       $time);
563
          `endif
564
          #10 $stop;
565
        end
566
      end
567
    end
568
 
569
    // set the signal - get register data in when write
570
    else if (md_transfer_cnt == 48)
571
    begin
572
      #4;
573
      if (!md_io_rd_wr) // write
574
      begin
575
        #1 md_get_reg_data_in = 1'b1;
576
    // check turn around cycle when write on clock 48
577
        if (md_io_reg !== 1'b0)
578
        begin
579
          // ERROR - turn around !
580
          `ifdef VERBOSE
581
          #1 $fdisplay(phy_log, "*E (%0t)(%m)MIIM - wrong 2. turn-around cycle before writing data in",
582
                       $time);
583
          `endif
584
          #10 $stop;
585
        end
586
      end
587
      else // read
588
      begin
589
        #1 md_get_reg_data_in = 1'b0;
590
      end
591
    end
592
 
593
    // reset the signal - enable md_io as output when read
594
    // reset the signal - get register data in when write
595
    // set the signal - put registered data in the register when write
596
    else if (md_transfer_cnt == 64)
597
    begin
598
      #1 md_io_enable = 1'b0;
599
      #4 md_get_reg_data_in = 1'b0;
600
      if (!md_io_rd_wr) // write
601
      begin
602
        if ((phy_address === `ETH_PHY_ADDR) || respond_to_all_phy_addr) // check the PHY address
603
        begin
604
          #1 md_put_reg_data_in = 1'b1;
605
          `ifdef VERBOSE
606
          $fdisplay(phy_log, "   (%0t)(%m)MIIM - received correct PHY ADDRESS: %x", $time, phy_address);
607
          $fdisplay(phy_log, "   (%0t)(%m)MIIM - WRITING to register %x COMPLETED!", $time, reg_address);
608
          `endif
609
        end
610
        else
611
        begin
612
          `ifdef VERBOSE
613
          #1 $fdisplay(phy_log, "*W (%0t)(%m)MIIM - received different PHY ADDRESS: %x", $time, phy_address);
614
          $fdisplay(phy_log, "*W (%0t)(%m)MIIM - NO WRITING to register %x !", $time, reg_address);
615
          `endif
616
        end
617
      end
618
      else // read
619
      begin
620
        `ifdef VERBOSE
621
        if ((phy_address === `ETH_PHY_ADDR) || respond_to_all_phy_addr) // check the PHY address
622
          #1 $fdisplay(phy_log, "   (%0t)(%m)MIIM - READING from register %x COMPLETED!",
623
                       $time, reg_address);
624
        else
625
          #1 $fdisplay(phy_log, "*W (%0t)(%m)MIIM - NO READING from register %x !", $time, reg_address);
626
        `endif
627
      end
628
    end
629
 
630
    // wait for one clock period
631
    @(posedge mdc_i)
632
      #1;
633
  end
634
end
635
 
636
//====================================================================
637
//
638
// PHY management (MIIM) REGISTERS
639
//
640
//====================================================================
641
//
642
//   Supported registers (normal operation):
643
//
644
// Addr | Register Name 
645
//--------------------------------------------------------------------
646
//   0  | Control reg.  
647
//   1  | Status reg. #1 
648
//   2  | PHY ID reg. 1 
649
//   3  | PHY ID reg. 2 
650
//----------------------
651
// Addr | Data MEMORY      |-->  for testing
652
//
653
//--------------------------------------------------------------------
654
//
655
// Control register
656
//  reg            control_bit15; // self clearing bit
657
//  reg    [14:10] control_bit14_10;
658
//  reg            control_bit9; // self clearing bit
659
//  reg    [8:0]   control_bit8_0;
660
// Status register
661
//  wire   [15:9]  status_bit15_9 = `SUPPORTED_SPEED_AND_PORT;
662
//  wire           status_bit8    = `EXTENDED_STATUS;
663
//  wire           status_bit7    = 1'b0; // reserved
664
//  reg    [6:0]   status_bit6_0  = `DEFAULT_STATUS;
665
// PHY ID register 1
666
//  wire   [15:0]  phy_id1        = `PHY_ID1;
667
// PHY ID register 2
668
//  wire   [15:0]  phy_id2        = {`PHY_ID2, `MAN_MODEL_NUM, `MAN_REVISION_NUM};
669
//--------------------------------------------------------------------
670
//
671
// Data MEMORY
672
//  reg    [15:0]  data_mem [0:31]; // 32 locations of 16-bit data width
673
//
674
//====================================================================
675
 
676
//////////////////////////////////////////////////////////////////////
677
//
678
// PHY management (MIIM) REGISTER control
679
//
680
//////////////////////////////////////////////////////////////////////
681
 
682
// wholy writable registers for walking ONE's on data, phy and reg. addresses
683
reg     registers_addr_data_test_operation;
684
 
685
// Non writable status registers
686
always
687
begin
688
  #1 status_bit6_0[6] = no_preamble;
689
  status_bit6_0[5] = 1'b0;
690
  status_bit6_0[3] = 1'b1;
691
  status_bit6_0[0] = 1'b1;
692
end
693
always@(posedge mrx_clk_o)
694
begin
695
  status_bit6_0[4] <= #1 1'b0;
696
  status_bit6_0[1] <= #1 1'b0;
697
end
698
initial
699
begin
700
  status_bit6_0[2] = 1'b1;
701
  registers_addr_data_test_operation = 0;
702
end
703
 
704
// Reading from a selected registers
705
always@(reg_address or registers_addr_data_test_operation or md_put_reg_data_out or
706
        control_bit15 or control_bit14_10 or control_bit9 or control_bit8_0 or
707
        status_bit15_9 or status_bit8 or status_bit7 or status_bit6_0 or
708
        phy_id1 or phy_id2)
709
begin
710
  if (registers_addr_data_test_operation) // test operation
711
  begin
712
    if (md_put_reg_data_out) // read enable
713
    begin
714
      register_bus_out = #1 data_mem[reg_address];
715
    end
716
  end
717
  else // normal operation
718
  begin
719
    if (md_put_reg_data_out) // read enable
720
    begin
721
      case (reg_address)
722
      5'h0:    register_bus_out = #1 {control_bit15, control_bit14_10, control_bit9, control_bit8_0};
723
      5'h1:    register_bus_out = #1 {status_bit15_9, status_bit8, status_bit7, status_bit6_0};
724
      5'h2:    register_bus_out = #1 phy_id1;
725
      5'h3:    register_bus_out = #1 phy_id2;
726
      default: register_bus_out = #1 16'hDEAD;
727
      endcase
728
    end
729
  end
730
end
731
 
732
// Self clear control signals
733
reg    self_clear_d0;
734
reg    self_clear_d1;
735
reg    self_clear_d2;
736
reg    self_clear_d3;
737
// Self clearing control
738
always@(posedge mdc_i or negedge m_rst_n_i)
739
begin
740
  if (!m_rst_n_i)
741
  begin
742
    self_clear_d0    <= #1 0;
743
    self_clear_d1    <= #1 0;
744
    self_clear_d2    <= #1 0;
745
    self_clear_d3    <= #1 0;
746
  end
747
  else
748
  begin
749
    self_clear_d0    <= #1 md_put_reg_data_in;
750
    self_clear_d1    <= #1 self_clear_d0;
751
    self_clear_d2    <= #1 self_clear_d1;
752
    self_clear_d3    <= #1 self_clear_d2;
753
  end
754
end
755
 
756
// Writing to a selected register
757
always@(posedge mdc_i or negedge m_rst_n_i)
758
begin
759
  if ((!m_rst_n_i) || (control_bit15))
760
  begin
761
    if (!registers_addr_data_test_operation) // normal operation
762
    begin
763
      control_bit15    <= #1 0;
764
      control_bit14_10 <= #1 {1'b0, (`LED_CFG1 || `LED_CFG2), `LED_CFG1, 2'b0};
765
      control_bit9     <= #1 0;
766
      control_bit8_0   <= #1 {`LED_CFG3, 8'b0};
767
    end
768
  end
769
  else
770
  begin
771
    if (registers_addr_data_test_operation) // test operation
772
    begin
773
      if (md_put_reg_data_in)
774
      begin
775
        data_mem[reg_address] <= #1 register_bus_in[15:0];
776
      end
777
    end
778
    else // normal operation
779
    begin
780
      // bits that are normaly written
781
      if (md_put_reg_data_in)
782
      begin
783
        case (reg_address)
784
        5'h0:
785
        begin
786
          control_bit14_10 <= #1 register_bus_in[14:10];
787
          control_bit8_0   <= #1 register_bus_in[8:0];
788
        end
789
        default:
790
        begin
791
        end
792
        endcase
793
      end
794
      // self cleared bits written
795
      if ((md_put_reg_data_in) && (reg_address == 5'h0))
796
      begin
797
        control_bit15 <= #1 register_bus_in[15];
798
        control_bit9  <= #1 register_bus_in[9];
799
      end
800
      else if (self_clear_d3) // self cleared bits cleared
801
      begin
802
        control_bit15 <= #1 1'b0;
803
        control_bit9  <= #1 1'b0;
804
      end
805
    end
806
  end
807
end
808
 
809
//////////////////////////////////////////////////////////////////////
810
//
811
// PHY <-> MAC control (RX and TX clocks are at the begining)
812
//
813
//////////////////////////////////////////////////////////////////////
814
 
815
// CARRIER SENSE & COLLISION
816
 
817
// MAC common signals
818
reg             mcoll_o;
819
reg             mcrs_o;
820
// Internal signals controling Carrier sense & Collision
821
  // MAC common signals generated when appropriate transfer
822
reg             mcrs_rx;
823
reg             mcrs_tx;
824
  // delayed mtxen_i signal for generating delayed tx carrier sense
825
reg             mtxen_d;
826
  // collision signal set or rest within task for controling collision
827
reg             task_mcoll;
828
  // carrier sense signal set or rest within task for controling carrier sense
829
reg             task_mcrs;
830 188 tadej
reg             task_mcrs_lost;
831
  // do not generate collision in half duplex - not normal operation
832
reg             no_collision_in_half_duplex;
833 169 mohor
  // generate collision in full-duplex mode also - not normal operation
834
reg             collision_in_full_duplex;
835 188 tadej
  // do not generate carrier sense in half duplex mode - not normal operation
836
reg             no_carrier_sense_in_tx_half_duplex;
837
reg             no_carrier_sense_in_rx_half_duplex;
838 169 mohor
  // generate carrier sense during TX in full-duplex mode also - not normal operation
839
reg             carrier_sense_in_tx_full_duplex;
840 188 tadej
  // do not generate carrier sense during RX in full-duplex mode - not normal operation
841
reg             no_carrier_sense_in_rx_full_duplex;
842 169 mohor
  // on RX: delay after carrier sense signal; on TX: carrier sense delayed (delay is one clock period)
843
reg             real_carrier_sense;
844
 
845
initial
846
begin
847
  mcrs_rx = 0;
848
  mcrs_tx = 0;
849
  task_mcoll = 0;
850
  task_mcrs = 0;
851 188 tadej
  task_mcrs_lost = 0;
852
  no_collision_in_half_duplex = 0;
853 169 mohor
  collision_in_full_duplex = 0;
854 188 tadej
  no_carrier_sense_in_tx_half_duplex = 0;
855
  no_carrier_sense_in_rx_half_duplex = 0;
856 169 mohor
  carrier_sense_in_tx_full_duplex = 0;
857 188 tadej
  no_carrier_sense_in_rx_full_duplex = 0;
858 169 mohor
  real_carrier_sense = 0;
859
end
860
 
861
// Collision
862
always@(m_rst_n_i or control_bit8_0 or collision_in_full_duplex or
863 188 tadej
        mcrs_rx or mcrs_tx or task_mcoll or no_collision_in_half_duplex
864 169 mohor
        )
865
begin
866
  if (!m_rst_n_i)
867
    mcoll_o = 0;
868
  else
869
  begin
870
    if (control_bit8_0[8]) // full duplex
871
    begin
872
      if (collision_in_full_duplex) // collision is usually not asserted in full duplex
873
      begin
874 188 tadej
        mcoll_o = ((mcrs_rx && mcrs_tx) || task_mcoll);
875 169 mohor
        `ifdef VERBOSE
876
        if (mcrs_rx && mcrs_tx)
877
          $fdisplay(phy_log, "   (%0t)(%m) Collision set in FullDuplex!", $time);
878
        if (task_mcoll)
879
          $fdisplay(phy_log, "   (%0t)(%m) Collision set in FullDuplex from TASK!", $time);
880
        `endif
881
      end
882
      else
883
      begin
884
        mcoll_o = task_mcoll;
885
        `ifdef VERBOSE
886
        if (task_mcoll)
887
          $fdisplay(phy_log, "   (%0t)(%m) Collision set in FullDuplex from TASK!", $time);
888
        `endif
889
      end
890
    end
891
    else // half duplex
892
    begin
893 188 tadej
      mcoll_o = ((mcrs_rx && mcrs_tx && !no_collision_in_half_duplex) ||
894
                  task_mcoll);
895 169 mohor
      `ifdef VERBOSE
896
      if (mcrs_rx && mcrs_tx)
897
        $fdisplay(phy_log, "   (%0t)(%m) Collision set in HalfDuplex!", $time);
898
      if (task_mcoll)
899
        $fdisplay(phy_log, "   (%0t)(%m) Collision set in HalfDuplex from TASK!", $time);
900
      `endif
901
    end
902
  end
903
end
904
 
905
// Carrier sense
906
always@(m_rst_n_i or control_bit8_0 or carrier_sense_in_tx_full_duplex or
907 188 tadej
        no_carrier_sense_in_rx_full_duplex or
908
        no_carrier_sense_in_tx_half_duplex or
909
        no_carrier_sense_in_rx_half_duplex or
910
        mcrs_rx or mcrs_tx or task_mcrs or task_mcrs_lost
911 169 mohor
        )
912
begin
913
  if (!m_rst_n_i)
914
    mcrs_o = 0;
915
  else
916
  begin
917
    if (control_bit8_0[8]) // full duplex
918
    begin
919
      if (carrier_sense_in_tx_full_duplex) // carrier sense is usually not asserted during TX in full duplex
920 188 tadej
        mcrs_o = ((mcrs_rx && !no_carrier_sense_in_rx_full_duplex) ||
921
                   mcrs_tx || task_mcrs) && !task_mcrs_lost;
922 169 mohor
      else
923 188 tadej
        mcrs_o = ((mcrs_rx && !no_carrier_sense_in_rx_full_duplex) ||
924
                   task_mcrs) && !task_mcrs_lost;
925 169 mohor
    end
926
    else // half duplex
927
    begin
928 188 tadej
      mcrs_o = ((mcrs_rx && !no_carrier_sense_in_rx_half_duplex) ||
929
                (mcrs_tx && !no_carrier_sense_in_tx_half_duplex) ||
930
                 task_mcrs) && !task_mcrs_lost;
931 169 mohor
    end
932
  end
933
end
934
 
935
// MAC TX CONTROL (RECEIVING AT PHY)
936
 
937
// storage memory for TX data received from MAC
938
reg     [7:0]  tx_mem [0:4194303]; // 4194304 locations (22 address lines) of 8-bit data width
939
reg    [31:0]  tx_mem_addr_in; // address for storing to TX memory
940
reg     [7:0]  tx_mem_data_in; // data for storing to TX memory
941
reg    [31:0]  tx_cnt; // counts nibbles
942
 
943
// control data of a TX packet for upper layer of testbench
944
reg            tx_preamble_ok;
945
reg            tx_sfd_ok;
946
// if there is a drible nibble, then tx packet is not byte aligned!
947
reg            tx_byte_aligned_ok;
948
// complete length of TX packet (Bytes) received (without preamble and SFD)
949
reg    [31:0]  tx_len;
950
 
951
// TX control
952
always@(posedge mtx_clk_o)
953
begin
954
  // storing data and basic checking of frame
955
  if (!m_rst_n_i)
956
  begin
957
    tx_cnt <= 0;
958
    tx_preamble_ok <= 0;
959
    tx_sfd_ok <= 0;
960
    tx_len <= 0;
961
  end
962
  else
963
  begin
964
    if (!mtxen_i)
965
    begin
966
      tx_cnt <= 0;
967
    end
968
    else
969
    begin
970
      // tx nibble counter
971
      tx_cnt <= tx_cnt + 1;
972
      // set initial values and check first preamble nibble
973
      if (tx_cnt == 0)
974
      begin
975
        `ifdef VERBOSE
976
        $fdisplay(phy_log, "   (%0t)(%m) TX frame started with tx_en set!", $time);
977
        `endif
978
        if (mtxd_i == 4'h5)
979
          tx_preamble_ok <= 1;
980
        else
981
          tx_preamble_ok <= 0;
982
        tx_sfd_ok <= 0;
983
        tx_byte_aligned_ok <= 0;
984
        tx_len <= 0;
985
//        tx_mem_addr_in <= 0;
986
      end
987
 
988
      // check preamble
989
      if ((tx_cnt > 0) && (tx_cnt <= 13))
990
      begin
991
        if ((tx_preamble_ok != 1) || (mtxd_i != 4'h5))
992
          tx_preamble_ok <= 0;
993
      end
994
      // check SFD
995
      if (tx_cnt == 14)
996
      begin
997
        `ifdef VERBOSE
998
        if (tx_preamble_ok == 1)
999
          $fdisplay(phy_log, "   (%0t)(%m) TX frame preamble OK!", $time);
1000
        else
1001
          $fdisplay(phy_log, "*E (%0t)(%m) TX frame preamble NOT OK!", $time);
1002
        `endif
1003
        if (mtxd_i == 4'h5)
1004
          tx_sfd_ok <= 1;
1005
        else
1006
          tx_sfd_ok <= 0;
1007
      end
1008
      if (tx_cnt == 15)
1009
      begin
1010
        if ((tx_sfd_ok != 1) || (mtxd_i != 4'hD))
1011
          tx_sfd_ok <= 0;
1012
      end
1013
 
1014
      // control for storing addresses, type/length, data and FCS to TX memory
1015
      if (tx_cnt > 15)
1016
      begin
1017
        if (tx_cnt == 16)
1018
        begin
1019
          `ifdef VERBOSE
1020
          if (tx_sfd_ok == 1)
1021
            $fdisplay(phy_log, "   (%0t)(%m) TX frame SFD OK!", $time);
1022
          else
1023
            $fdisplay(phy_log, "*E (%0t)(%m) TX frame SFD NOT OK!", $time);
1024
          `endif
1025
        end
1026
 
1027
        if (tx_cnt[0] == 0)
1028
        begin
1029
          tx_mem_data_in[3:0] <= mtxd_i; // storing LSB nibble
1030
          tx_byte_aligned_ok <= 0; // if transfer will stop after this, then there was drible nibble
1031
        end
1032
        else
1033
        begin
1034
          tx_mem[tx_mem_addr_in[21:0]] <= {mtxd_i, tx_mem_data_in[3:0]}; // storing data into tx memory
1035
          tx_len <= tx_len + 1; // enlarge byte length counter
1036
          tx_byte_aligned_ok <= 1; // if transfer will stop after this, then transfer is byte alligned
1037
          tx_mem_addr_in <= tx_mem_addr_in + 1'b1;
1038
        end
1039
      end
1040
    end
1041
  end
1042
 
1043
  // generating CARRIER SENSE for TX with or without delay
1044
  if (!m_rst_n_i)
1045
  begin
1046
    mcrs_tx <= 0;
1047
    mtxen_d <= 0;
1048
  end
1049
  else
1050
  begin
1051
    if (!real_carrier_sense)
1052
    begin
1053
      mtxen_d <= mtxen_i;
1054
      mcrs_tx <= mtxen_i;
1055
    end
1056
    else
1057
    begin
1058
      mtxen_d <= mtxen_i;
1059
      mcrs_tx <= mtxen_d;
1060
    end
1061
  end
1062
end
1063
 
1064
`ifdef VERBOSE
1065
reg             frame_started;
1066
 
1067
initial
1068
begin
1069
  frame_started = 0;
1070
end
1071
always@(posedge mtxen_i)
1072
begin
1073
  frame_started <= 1;
1074
end
1075
always@(negedge mtxen_i)
1076
begin
1077
  if (frame_started)
1078
  begin
1079
    $fdisplay(phy_log, "   (%0t)(%m) TX frame ended with tx_en reset!", $time);
1080
    frame_started <= 0;
1081
  end
1082
end
1083
 
1084
always@(posedge mrxerr_o)
1085
begin
1086
  $fdisplay(phy_log, "   (%0t)(%m) RX frame ERROR signal was set!", $time);
1087
end
1088
`endif
1089
 
1090
//////////////////////////////////////////////////////////////////////
1091
// 
1092
// Tasks for PHY <-> MAC transactions
1093
// 
1094
//////////////////////////////////////////////////////////////////////
1095
 
1096
initial
1097
begin
1098
  tx_mem_addr_in = 0;
1099
end
1100
 
1101
// setting the address of tx_mem, to set the starting point of tx packet
1102
task set_tx_mem_addr;
1103
  input [31:0] tx_mem_address;
1104
begin
1105
  #1 tx_mem_addr_in = tx_mem_address;
1106
end
1107
endtask // set_tx_mem_addr
1108
 
1109
// storage memory for RX data to be transmited to MAC
1110
reg     [7:0]  rx_mem [0:4194303]; // 4194304 locations (22 address lines) of 8-bit data width
1111
 
1112
// MAC RX signals
1113
reg     [3:0]   mrxd_o;
1114
reg             mrxdv_o;
1115
reg             mrxerr_o;
1116
 
1117
initial
1118
begin
1119
  mrxd_o = 0;
1120
  mrxdv_o = 0;
1121
  mrxerr_o = 0;
1122
  mcrs_rx = 0;
1123
end
1124
 
1125
task send_rx_packet;
1126
  input  [(8*32)-1:0] preamble_data; // preamble data to be sent
1127
  input   [3:0] preamble_len; // length of preamble - max is 8
1128
  input   [7:0] sfd_data; // SFD data to be sent
1129
  input  [31:0] start_addr; // start address
1130
  input  [31:0] len; // length of frame in Bytes (without preamble and SFD)
1131
  input         plus_drible_nibble; // if length is longer for one nibble
1132
  integer       rx_cnt;
1133
  reg    [31:0] rx_mem_addr_in; // address for reading from RX memory       
1134
  reg     [7:0] rx_mem_data_out; // data for reading from RX memory
1135
begin
1136
  @(posedge mrx_clk_o);
1137
  // generating CARRIER SENSE for TX with or without delay
1138
  if (real_carrier_sense)
1139
    #1 mcrs_rx = 1;
1140
  else
1141
    #1 mcrs_rx = 0;
1142
  @(posedge mrx_clk_o);
1143
  #1 mcrs_rx = 1;
1144
  #1 mrxdv_o = 1;
1145
  `ifdef VERBOSE
1146
  $fdisplay(phy_log, "   (%0t)(%m) RX frame started with rx_dv set!", $time);
1147
  `endif
1148
  // set initial rx memory address
1149
  rx_mem_addr_in = start_addr;
1150
 
1151
  // send preamble
1152
  for (rx_cnt = 0; (rx_cnt < preamble_len) || (rx_cnt < 8); rx_cnt = rx_cnt + 1)
1153
  begin
1154
    #1 mrxd_o = preamble_data[3:0];
1155
    #1 preamble_data = preamble_data >> 4;
1156
    @(posedge mrx_clk_o);
1157
  end
1158
 
1159
  // send SFD
1160
  for (rx_cnt = 0; rx_cnt < 2; rx_cnt = rx_cnt + 1)
1161
  begin
1162
    #1 mrxd_o = sfd_data[3:0];
1163
    #1 sfd_data = sfd_data >> 4;
1164
    @(posedge mrx_clk_o);
1165
  end
1166
  `ifdef VERBOSE
1167
  $fdisplay(phy_log, "   (%0t)(%m) RX frame preamble and SFD sent!", $time);
1168
  `endif
1169
  // send packet's addresses, type/length, data and FCS
1170
  for (rx_cnt = 0; rx_cnt < len; rx_cnt = rx_cnt + 1)
1171
  begin
1172
    @(posedge mrx_clk_o);
1173
    #1;
1174
    rx_mem_data_out = rx_mem[rx_mem_addr_in[21:0]];
1175
    mrxd_o = rx_mem_data_out[3:0];
1176
    @(posedge mrx_clk_o);
1177
    #1;
1178
    mrxd_o = rx_mem_data_out[7:4];
1179
    rx_mem_addr_in = rx_mem_addr_in + 1;
1180
    #1;
1181
  end
1182
  if (plus_drible_nibble)
1183
  begin
1184
    @(posedge mrx_clk_o);
1185
    #1;
1186
    rx_mem_data_out = rx_mem[rx_mem_addr_in[21:0]];
1187
    mrxd_o = rx_mem_data_out[3:0];
1188
  end
1189
  `ifdef VERBOSE
1190
  $fdisplay(phy_log, "   (%0t)(%m) RX frame addresses, type/length, data and FCS sent!", $time);
1191
  `endif
1192
  @(posedge mrx_clk_o);
1193
  #1 mcrs_rx = 0;
1194
  #1 mrxdv_o = 0;
1195
  `ifdef VERBOSE
1196
  $fdisplay(phy_log, "   (%0t)(%m) RX frame ended with rx_dv reset!", $time);
1197
  `endif
1198
end
1199
endtask // send_rx_packet
1200
 
1201
 
1202
 
1203
task GetDataOnMRxD;
1204
  input [15:0] Len;
1205
  input [31:0] TransferType;
1206
  integer tt;
1207
 
1208
  begin
1209
    @ (posedge mrx_clk_o);
1210
    #1 mrxdv_o=1'b1;
1211
 
1212
    for(tt=0; tt<15; tt=tt+1)
1213
    begin
1214
      mrxd_o=4'h5;              // preamble
1215
      @ (posedge mrx_clk_o);
1216
      #1;
1217
    end
1218
 
1219
    mrxd_o=4'hd;                // SFD
1220
 
1221
    for(tt=1; tt<(Len+1); tt=tt+1)
1222
    begin
1223
      @ (posedge mrx_clk_o);
1224
      #1;
1225
      if(TransferType == `UNICAST_XFR && tt == 1)
1226
        mrxd_o = 4'h0;   // Unicast transfer
1227
      else if(TransferType == `BROADCAST_XFR && tt < 7)
1228
        mrxd_o = 4'hf;
1229
      else
1230
        mrxd_o = tt[3:0]; // Multicast transfer
1231
 
1232
      @ (posedge mrx_clk_o);
1233
      #1;
1234
 
1235
      if(TransferType == `BROADCAST_XFR && tt == 6)
1236
        mrxd_o = 4'he;
1237
      else
1238
 
1239
      if(TransferType == `BROADCAST_XFR && tt < 7)
1240
        mrxd_o = 4'hf;
1241
      else
1242
        mrxd_o = tt[7:4];
1243
    end
1244
 
1245
    @ (posedge mrx_clk_o);
1246
    #1;
1247
    mrxdv_o = 1'b0;
1248
  end
1249
endtask // GetDataOnMRxD
1250
 
1251
 
1252
//////////////////////////////////////////////////////////////////////
1253
//
1254
// Tastks for controling PHY statuses and rx error
1255
//
1256
//////////////////////////////////////////////////////////////////////
1257
 
1258
// Link control tasks
1259
task link_up_down;
1260
  input   test_op;
1261
begin
1262
  #1 status_bit6_0[2] = test_op; // 1 - link up; 0 - link down
1263
end
1264
endtask
1265
 
1266
// RX error
1267
task rx_err;
1268
  input   test_op;
1269
begin
1270
  #1 mrxerr_o = test_op; // 1 - RX error set; 0 - RX error reset
1271
end
1272
endtask
1273
 
1274
//////////////////////////////////////////////////////////////////////
1275
//
1276
// Tastks for controling PHY carrier sense and collision
1277
//
1278
//////////////////////////////////////////////////////////////////////
1279
 
1280
// Collision
1281
task collision;
1282
  input   test_op;
1283
begin
1284
  #1 task_mcoll = test_op;
1285
end
1286
endtask
1287
 
1288
// Carrier sense
1289
task carrier_sense;
1290
  input   test_op;
1291
begin
1292
  #1 task_mcrs = test_op;
1293
end
1294
endtask
1295
 
1296 188 tadej
// Carrier sense lost - higher priority than Carrier sense task
1297
task carrier_sense_lost;
1298
  input   test_op;
1299
begin
1300
  #1 task_mcrs_lost = test_op;
1301
end
1302
endtask
1303
 
1304
// No collision detection in half duplex
1305
task no_collision_hd_detect;
1306
  input   test_op;
1307
begin
1308
  #1 no_collision_in_half_duplex = test_op;
1309
end
1310
endtask
1311
 
1312 169 mohor
// Collision detection in full duplex also
1313
task collision_fd_detect;
1314
  input   test_op;
1315
begin
1316
  #1 collision_in_full_duplex = test_op;
1317
end
1318
endtask
1319
 
1320 188 tadej
// No carrier sense detection at TX in half duplex
1321
task no_carrier_sense_tx_hd_detect;
1322
  input   test_op;
1323
begin
1324
  #1 no_carrier_sense_in_tx_half_duplex = test_op;
1325
end
1326
endtask
1327
 
1328
// No carrier sense detection at RX in half duplex
1329
task no_carrier_sense_rx_hd_detect;
1330
  input   test_op;
1331
begin
1332
  #1 no_carrier_sense_in_rx_half_duplex = test_op;
1333
end
1334
endtask
1335
 
1336 169 mohor
// Carrier sense detection at TX in full duplex also
1337
task carrier_sense_tx_fd_detect;
1338
  input   test_op;
1339
begin
1340
  #1 carrier_sense_in_tx_full_duplex = test_op;
1341
end
1342
endtask
1343
 
1344 188 tadej
// No carrier sense detection at RX in full duplex
1345
task no_carrier_sense_rx_fd_detect;
1346
  input   test_op;
1347
begin
1348
  #1 no_carrier_sense_in_rx_full_duplex = test_op;
1349
end
1350
endtask
1351
 
1352
// Set real delay on carrier sense signal (and therefor collision signal)
1353 169 mohor
task carrier_sense_real_delay;
1354
  input   test_op;
1355
begin
1356
  #1 real_carrier_sense = test_op;
1357
end
1358
endtask
1359
 
1360
//////////////////////////////////////////////////////////////////////
1361
//
1362
// Tastks for controling PHY management test operation
1363
//
1364
//////////////////////////////////////////////////////////////////////
1365
 
1366
// Set registers to test operation and respond to all phy addresses
1367
task test_regs;
1368
  input   test_op;
1369
begin
1370
  #1 registers_addr_data_test_operation = test_op;
1371
  respond_to_all_phy_addr = test_op;
1372
end
1373
endtask
1374
 
1375
// Clears data memory for testing the MII
1376
task clear_test_regs;
1377
  integer i;
1378
begin
1379
  for (i = 0; i < 32; i = i + 1)
1380
  begin
1381
    #1 data_mem[i] = 16'h0;
1382
  end
1383
end
1384
endtask
1385
 
1386
// Accept frames with preamble suppresed
1387
task preamble_suppresed;
1388
  input   test_op;
1389
begin
1390
  #1 no_preamble = test_op;
1391
  md_transfer_cnt_reset = 1'b1;
1392
  @(posedge mdc_i);
1393
  #1 md_transfer_cnt_reset = 1'b0;
1394
end
1395
endtask
1396
 
1397
 
1398
 
1399
 
1400
 
1401
endmodule
1402
 

powered by: WebSVN 2.1.0

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