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

Subversion Repositories turbo8051

[/] [turbo8051/] [trunk/] [rtl/] [gmac/] [mac/] [g_md_intf.v] - Blame information for rev 77

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 dinesha
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  Tubo 8051 cores MAC Interface Module                        ////
4
////                                                              ////
5
////  This file is part of the Turbo 8051 cores project           ////
6
////  http://www.opencores.org/cores/turbo8051/                   ////
7
////                                                              ////
8
////  Description                                                 ////
9
////  Turbo 8051 definitions.                                     ////
10
////                                                              ////
11
////  To Do:                                                      ////
12
////    nothing                                                   ////
13
////                                                              ////
14
////  Author(s):                                                  ////
15
////      - Dinesh Annayya, dinesha@opencores.org                 ////
16
////                                                              ////
17 76 dinesha
////  Revision : Mar 2, 2011                                      //// 
18
////                                                              ////
19 12 dinesha
//////////////////////////////////////////////////////////////////////
20
////                                                              ////
21
//// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
22
////                                                              ////
23
//// This source file may be used and distributed without         ////
24
//// restriction provided that this copyright statement is not    ////
25
//// removed from the file and that any derivative work contains  ////
26
//// the original copyright notice and the associated disclaimer. ////
27
////                                                              ////
28
//// This source file is free software; you can redistribute it   ////
29
//// and/or modify it under the terms of the GNU Lesser General   ////
30
//// Public License as published by the Free Software Foundation; ////
31
//// either version 2.1 of the License, or (at your option) any   ////
32
//// later version.                                               ////
33
////                                                              ////
34
//// This source is distributed in the hope that it will be       ////
35
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
36
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
37
//// PURPOSE.  See the GNU Lesser General Public License for more ////
38
//// details.                                                     ////
39
////                                                              ////
40
//// You should have received a copy of the GNU Lesser General    ////
41
//// Public License along with this source; if not, download it   ////
42
//// from http://www.opencores.org/lgpl.shtml                     ////
43
////                                                              ////
44
//////////////////////////////////////////////////////////////////////
45
 
46
/***************************************************************
47
  Description:
48
 
49
  md_intf.v: This verilog file is for the mdio interface of the mac
50
                This block enables the station to communicate with the
51
                PHYs. This interface is kicked of by a go command from
52
                the application. This intiates the read and write operation
53
                to the PHY. Upon completion of the operation it returns
54
                a indication called command done with the status of such
55
                operation.
56
 
57
***************************************************************/
58
/************** MODULE DECLARATION ****************************/
59
 
60
module g_md_intf(
61
                  scan_mode,
62
                  reset_n,
63
                  mdio_clk,
64
                  mdio_in,
65
                  mdio_outen_reg,
66
                  mdio_out_reg,
67
                  mdio_regad,
68
                  mdio_phyad,
69
                  mdio_op,
70
                  go_mdio,
71
                  mdio_datain,
72
                  mdio_dataout,
73
                  mdio_cmd_done,
74
                  mdio_stat,
75
                  mdc
76
                  );
77
 
78
 
79
parameter FIVE       = 5'h5;
80
parameter SIXTEEN    = 5'd16;
81
parameter THIRTY_TWO = 5'd31;
82
parameter WRITE      = 1;
83
 
84
/******* INPUT & OUTPUT DECLARATIONS *************************/
85
 
86
  input scan_mode ; // scan_mode = 1
87
  input reset_n;       // reset from mac application interface
88
  input mdio_in;             // Input signal used to read data from PHY
89
  input mdio_clk;            // Input signal used to read data from PHY
90
  input[4:0] mdio_regad;     // register address for the current PHY operation
91
  input[4:0] mdio_phyad;     // Phy address to which the current operation is intended
92
  input mdio_op;             // 1 = READ  0 = WRITE
93
  input go_mdio;             // This is go command from the application for a MDIO
94
                             // transfer
95
  input[15:0] mdio_datain;   // 16 bit Write value from application to MDIO block
96
  output[15:0] mdio_dataout; // 16 bit Read value for a MDIO transfer
97
  output mdio_cmd_done;      // This is from MDIO to indicate mdio command completion
98
  output mdio_stat;          // Status of completion. 0 = No error 1= Error
99
  output mdio_out_reg;           // Output signal used to write data to PHY
100
  output mdio_outen_reg;        // Enable signal 1= Output mode on 0 = Input mode
101
  output mdc;                // This is the MDIO clock
102
 
103
/******* WIRE & REG DECLARATION FOR INPUT AND OUTPUTS ********/
104
 wire mdc;
105
 wire [15:0] mdio_dataout;
106
 wire go_mdio_sync;
107
 reg mdio_stat;
108
 reg mdio_cmd_done;
109
 reg mdio_out_en;
110
 reg mdio_out;
111
 
112
 half_dup_dble_reg U_dble_reg1 (
113
                         //outputs
114
                         .sync_out_pulse(go_mdio_sync),
115
                         //inputs
116
                         .in_pulse(go_mdio),
117
                         .dest_clk(mdio_clk),
118
                         .reset_n(reset_n)
119
                         );
120
 
121
 
122
 
123
 
124
/*** REG & WIRE DECLARATIONS FOR LOCAL SIGNALS ***************/
125
 reg[3:0] mdio_cur_st;
126
 reg[3:0] mdio_nxt_st;
127
 parameter mdio_idle_st= 4'd0,
128
                mdio_idle1_st = 4'd1,
129
                mdio_sfd1_st= 4'd2,
130
                mdio_sfd2_st= 4'd3,
131
                mdio_op1_st=  4'd4,
132
                mdio_op2_st=  4'd5,
133
                mdio_phyaddr_st= 4'd6,
134
                mdio_regaddr_st= 4'd7,
135
                mdio_turnar_st=  4'd8,
136
                mdio_wrturn_st=  4'd9,
137
                mdio_rdturn_st=  4'd10,
138
                mdio_read_st=    4'd11,
139
                mdio_write_st=   4'd12,
140
                mdio_complete_st= 4'd13,
141
                mdio_preamble_st= 4'd14;
142
 
143
 reg operation;
144
 reg phyaddr_mux_sel;
145
 reg regaddr_mux_sel;
146
 reg write_data_mux_sel;
147
 reg read_data_mux_sel;
148
 wire[4:0] inc_temp_count;
149
 reg[4:0] temp_count;
150
 reg reset_temp_count;
151
 reg inc_count;
152
 reg[4:0] phy_addr;
153
 reg[4:0] reg_addr;
154
 reg[15:0] transmit_data;
155
 reg[15:0] receive_data;
156
 reg       set_mdio_stat,clr_mdio_stat;
157
 
158
/***************** WIRE ASSIGNMENTS *************************/
159
 assign mdc = mdio_clk;
160
 assign mdio_dataout = receive_data;
161
 
162
/******** SEQUENTIAL LOGIC **********************************/
163
 
164
 always @(mdio_cur_st or go_mdio_sync or inc_temp_count or
165
          transmit_data or operation or phy_addr or reg_addr or temp_count or mdio_in)
166
   begin
167
     mdio_nxt_st = mdio_cur_st;
168
     inc_count = 1'b0;
169
     //mdio_cmd_done = 1'b0;
170
     mdio_out = 1'b0;
171
     mdio_out_en = 1'b0;
172
     set_mdio_stat = 1'b0;
173
     clr_mdio_stat = 1'b0;
174
     phyaddr_mux_sel = 1'b0;
175
     read_data_mux_sel = 1'b0;
176
     regaddr_mux_sel = 1'b0;
177
     reset_temp_count = 1'b0;
178
     write_data_mux_sel = 1'b0;
179
 
180
      casex(mdio_cur_st )       // synopsys parallel_case full_case
181
 
182
        mdio_idle_st:
183
          // This state waits for signal go_mdio
184
          // upon this command from config block
185
          // mdio state machine starts to send
186
          // SOF delimter
187
          begin
188
            if(~go_mdio_sync)
189
              mdio_nxt_st = mdio_idle1_st; //mdio_sfd1_st;
190
            else
191
              mdio_nxt_st = mdio_idle_st;
192
          end
193
 
194
      mdio_idle1_st:
195
         begin
196
           if (go_mdio_sync)
197
             mdio_nxt_st = mdio_preamble_st;
198
           else
199
             mdio_nxt_st = mdio_idle1_st;
200
         end
201
 
202
      mdio_preamble_st:
203
        begin
204
          clr_mdio_stat = 1'b1;
205
          mdio_out_en = 1'b1;
206
          mdio_out = 1'b1;
207
          if (temp_count == THIRTY_TWO)
208
            begin
209
              mdio_nxt_st = mdio_sfd1_st;
210
              reset_temp_count = 1'b1;
211
            end
212
          else
213
            begin
214
              inc_count = 1'b1;
215
              mdio_nxt_st = mdio_preamble_st;
216
            end
217
        end
218
 
219
        mdio_sfd1_st:
220
          // This state shifts the first bit
221
          // of Start of Frame De-limiter
222
          begin
223
            mdio_out_en = 1'b1;
224
            mdio_out = 1'b0;
225
            mdio_nxt_st = mdio_sfd2_st;
226
          end
227
 
228
        mdio_sfd2_st:
229
          // This state shifts the second bit
230
          // of Start of Frame De-limiter
231
          begin
232
            mdio_out_en = 1'b1;
233
            mdio_out = 1'b1;
234
            mdio_nxt_st = mdio_op1_st;
235
          end
236
 
237
        mdio_op1_st:
238
          // This state shifts the first bit
239
          // of type of operation read/write
240
          begin
241
            mdio_out_en = 1'b1;
242
            if(operation)
243
             mdio_out = 1'b0;
244
            else
245
             mdio_out = 1'b1;
246
            mdio_nxt_st = mdio_op2_st;
247
          end
248
 
249
        mdio_op2_st:
250
          // This state shifts the second bit
251
          // of type of operation read/write and
252
          // determines the appropriate next state
253
          // needed for such operation
254
          begin
255
            mdio_out_en = 1'b1;
256
            mdio_nxt_st = mdio_phyaddr_st;
257
            if(operation)
258
             mdio_out = 1'b1;
259
            else
260
             mdio_out = 1'b0;
261
          end
262
 
263
        mdio_phyaddr_st:
264
          // This state shifts the phy-address on the mdio
265
          begin
266
            mdio_out_en = 1'b1;
267
            phyaddr_mux_sel = 1'b1;
268
            if(inc_temp_count == FIVE)
269
             begin
270
              reset_temp_count = 1'b1;
271
              mdio_out = phy_addr[4];
272
              mdio_nxt_st = mdio_regaddr_st;
273
             end
274
            else
275
             begin
276
              inc_count = 1'b1;
277
              mdio_out = phy_addr[4];
278
              mdio_nxt_st = mdio_phyaddr_st;
279
             end
280
          end
281
 
282
        mdio_regaddr_st:
283
          // This state shifts the register in the phy to which
284
          // this operation is intended
285
          begin
286
            mdio_out_en = 1'b1;
287
            regaddr_mux_sel = 1'b1;
288
            if(inc_temp_count == FIVE)
289
             begin
290
              reset_temp_count = 1'b1;
291
              mdio_out = reg_addr[4];
292
              mdio_nxt_st = mdio_turnar_st;
293
             end
294
            else
295
             begin
296
              inc_count = 1'b1;
297
              mdio_out = reg_addr[4];
298
              mdio_nxt_st = mdio_regaddr_st;
299
             end
300
          end
301
 
302
        mdio_turnar_st:
303
          // This state determines whether the output enable
304
          // needs to on or of based on the type of command
305
          begin
306
            mdio_out = 1'b1;
307
            if(operation)
308
            begin
309
             mdio_out_en = 1'b1;
310
             mdio_nxt_st = mdio_wrturn_st;
311
            end
312
            else
313
             begin
314
             mdio_out_en = 1'b0;
315
             mdio_nxt_st = mdio_rdturn_st;
316
             end
317
          end
318
 
319
        mdio_wrturn_st:
320
          // This state is used for write turn around
321
          begin
322
            mdio_out_en = 1'b1;
323
            mdio_out = 1'b0;
324
            mdio_nxt_st = mdio_write_st;
325
          end
326
 
327
        mdio_rdturn_st:
328
          // This state is used to read turn around state
329
          // the output enable is switched off
330
          begin
331
            if (mdio_in)
332
                set_mdio_stat = 1'b1;
333
            mdio_out_en = 1'b0;
334
            mdio_nxt_st = mdio_read_st;
335
          end
336
 
337
        mdio_write_st:
338
          // This state transfers the 16 bits of data to the
339
          // PHY
340
          begin
341
            mdio_out_en = 1'b1;
342
            write_data_mux_sel = 1'b1;
343
            if(inc_temp_count == SIXTEEN)
344
             begin
345
              reset_temp_count = 1'b1;
346
              mdio_out = transmit_data[15];
347
              mdio_nxt_st = mdio_complete_st;
348
             end
349
            else
350
             begin
351
              inc_count = 1'b1;
352
              mdio_out = transmit_data[15];
353
              mdio_nxt_st = mdio_write_st;
354
             end
355
          end
356
 
357
        mdio_read_st:
358
          // This state receives the 16 bits of data from the 
359
          // PHY
360
          begin
361
            mdio_out_en = 1'b0;
362
            read_data_mux_sel = 1'b1;
363
            if(inc_temp_count == SIXTEEN)
364
             begin
365
              reset_temp_count = 1'b1;
366
              mdio_nxt_st = mdio_complete_st;
367
             end
368
            else
369
             begin
370
              inc_count = 1'b1;
371
              mdio_nxt_st = mdio_read_st;
372
             end
373
          end
374
 
375
        mdio_complete_st:
376
          // This completes the mdio transfers indicates to the
377
          // application of such complete
378
          begin
379
            mdio_nxt_st = mdio_idle_st;
380
            mdio_out_en = 1'b0;
381
            read_data_mux_sel = 1'b0;
382
            //mdio_cmd_done = 1'b1;
383
//          mdio_stat = 1'b0;
384
          end
385
      endcase
386
   end
387
always @(mdio_cur_st)
388
 mdio_cmd_done  = (mdio_cur_st == 4'd13);
389
 
390
 
391
always @(posedge mdio_clk or negedge reset_n)
392
begin
393
    if (!reset_n)
394
      mdio_stat <= 1'b0;
395
    else if (set_mdio_stat)
396
      mdio_stat <= 1'b1;
397
    else if (clr_mdio_stat)
398
      mdio_stat <= 1'b0;
399
end
400
 
401
 
402
// This latches the PHY address, Register address and the
403
// Transmit data and the type of operation
404
//
405
 always @(posedge mdio_clk or negedge reset_n)
406
  begin
407
   if(!reset_n)
408
     begin
409
       phy_addr <= 5'd0;
410
       reg_addr <= 5'd0;
411
       transmit_data <= 16'd0;
412
       operation <= 1'b0;
413
       receive_data <= 16'd0;
414
     end
415
   else
416
     begin
417
       if(go_mdio_sync)
418
         begin
419
           phy_addr <= mdio_phyad;
420
           reg_addr <= mdio_regad;
421
           if(mdio_op == WRITE)
422
             begin
423
               operation <= 1'b1;
424
               transmit_data <= mdio_datain;
425
             end
426
         end
427
       else
428
         begin
429
           operation <= 1'b0;
430
           phy_addr <= phy_addr;
431
           transmit_data <= transmit_data;
432
           reg_addr <= reg_addr;
433
         end // else: !if(go_mdio)
434
 
435
           if(phyaddr_mux_sel)
436
             begin
437
             /*
438
               phy_addr[0] <= phy_addr[1];
439
               phy_addr[1] <= phy_addr[2];
440
               phy_addr[2] <= phy_addr[3];
441
               phy_addr[3] <= phy_addr[4];
442
             */
443
               phy_addr[4] <= phy_addr[3];
444
               phy_addr[3] <= phy_addr[2];
445
               phy_addr[2] <= phy_addr[1];
446
               phy_addr[1] <= phy_addr[0];
447
             end
448
           if(regaddr_mux_sel)
449
             begin
450
               reg_addr[4] <= reg_addr[3];
451
               reg_addr[3] <= reg_addr[2];
452
               reg_addr[2] <= reg_addr[1];
453
               reg_addr[1] <= reg_addr[0];
454
             end
455
           if(write_data_mux_sel)
456
             begin
457
               transmit_data[15] <= transmit_data[14];
458
               transmit_data[14] <= transmit_data[13];
459
               transmit_data[13] <= transmit_data[12];
460
               transmit_data[12] <= transmit_data[11];
461
               transmit_data[11] <= transmit_data[10];
462
               transmit_data[10] <= transmit_data[9];
463
               transmit_data[9] <= transmit_data[8];
464
               transmit_data[8] <= transmit_data[7];
465
               transmit_data[7] <= transmit_data[6];
466
               transmit_data[6] <= transmit_data[5];
467
               transmit_data[5] <= transmit_data[4];
468
               transmit_data[4] <= transmit_data[3];
469
               transmit_data[3] <= transmit_data[2];
470
               transmit_data[2] <= transmit_data[1];
471
               transmit_data[1] <= transmit_data[0];
472
             end
473
           if(read_data_mux_sel)
474
             begin
475
               receive_data[0] <= mdio_in;
476
               receive_data[1] <= receive_data[0];
477
               receive_data[2] <= receive_data[1];
478
               receive_data[3] <= receive_data[2];
479
               receive_data[4] <= receive_data[3];
480
               receive_data[5] <= receive_data[4];
481
               receive_data[6] <= receive_data[5];
482
               receive_data[7] <= receive_data[6];
483
               receive_data[8] <= receive_data[7];
484
               receive_data[9] <= receive_data[8];
485
               receive_data[10] <= receive_data[9];
486
               receive_data[11] <= receive_data[10];
487
               receive_data[12] <= receive_data[11];
488
               receive_data[13] <= receive_data[12];
489
               receive_data[14] <= receive_data[13];
490
               receive_data[15] <= receive_data[14];
491
             end
492
     end // else: !if(!reset_n)
493
  end // always @ (posedge mdio_clk or negedge reset_n)
494
 
495
 // Temporary counter used to shift the data on the mdio line
496
 // This is also used to receive data on the line
497
 assign inc_temp_count = temp_count + 5'h1;
498
 
499
 always @(posedge mdio_clk or negedge reset_n)
500
   begin
501
     if(!reset_n)
502
        mdio_cur_st <= mdio_idle_st;
503
     else
504
        mdio_cur_st <= mdio_nxt_st;
505
   end // always @ (posedge mdio_clk or negedge reset_n)
506
 
507
   reg  mdio_outen_reg, mdio_out_reg;
508
 
509
  //----------------------------------------------
510
  // Note: Druring Scan Mode inverted mdio_clk used for 
511
  // mdio_outen_reg & mdio_out_reg
512
  //----------------------------------------------- 
513
  wire mdio_clk_scan = (scan_mode) ? !mdio_clk : mdio_clk;
514
 
515
   always @(negedge mdio_clk_scan or negedge reset_n)
516
   begin
517
     if(!reset_n)
518
     begin
519
        mdio_outen_reg <= 1'b0;
520
        mdio_out_reg <= 1'b0;
521
     end
522
     else
523
     begin
524
        mdio_outen_reg <= mdio_out_en;
525
        mdio_out_reg <= mdio_out;
526
     end
527
 
528
   end // always @ (posedge mdio_clk or negedge reset_n)
529
 
530
 always @(posedge mdio_clk or negedge reset_n)
531
   begin
532
     if(!reset_n)
533
        temp_count <= 5'b0;
534
     else
535
       begin
536
         if(reset_temp_count)
537
           temp_count <= 5'b0;
538
         else if(inc_count)
539
           temp_count <= inc_temp_count;
540
       end // else: !if(reset_n)
541
   end // always @ (posedge mdio_clk or negedge reset_n)
542
 
543
 
544
 
545
endmodule
546
 
547
 

powered by: WebSVN 2.1.0

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