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 76

Go to most recent revision | 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_out = 1'b0; naveen 120199
247
            mdio_nxt_st = mdio_op2_st;
248
          end
249
 
250
        mdio_op2_st:
251
          // This state shifts the second bit
252
          // of type of operation read/write and
253
          // determines the appropriate next state
254
          // needed for such operation
255
          begin
256
            mdio_out_en = 1'b1;
257
            mdio_nxt_st = mdio_phyaddr_st;
258
            if(operation)
259
             mdio_out = 1'b1;
260
            else
261
             mdio_out = 1'b0;
262
          end
263
 
264
        mdio_phyaddr_st:
265
          // This state shifts the phy-address on the mdio
266
          begin
267
            mdio_out_en = 1'b1;
268
            phyaddr_mux_sel = 1'b1;
269
            if(inc_temp_count == FIVE)
270
             begin
271
              reset_temp_count = 1'b1;
272
              mdio_out = phy_addr[4];
273
              mdio_nxt_st = mdio_regaddr_st;
274
             end
275
            else
276
             begin
277
              inc_count = 1'b1;
278
              mdio_out = phy_addr[4];
279
              mdio_nxt_st = mdio_phyaddr_st;
280
             end
281
          end
282
 
283
        mdio_regaddr_st:
284
          // This state shifts the register in the phy to which
285
          // this operation is intended
286
          begin
287
            mdio_out_en = 1'b1;
288
            regaddr_mux_sel = 1'b1;
289
            if(inc_temp_count == FIVE)
290
             begin
291
              reset_temp_count = 1'b1;
292
              mdio_out = reg_addr[4];
293
              mdio_nxt_st = mdio_turnar_st;
294
             end
295
            else
296
             begin
297
              inc_count = 1'b1;
298
              mdio_out = reg_addr[4];
299
              mdio_nxt_st = mdio_regaddr_st;
300
             end
301
          end
302
 
303
        mdio_turnar_st:
304
          // This state determines whether the output enable
305
          // needs to on or of based on the type of command
306
          begin
307
            //mdio_out_en = 1'b1;naveen 011299
308
            mdio_out = 1'b1;
309
            if(operation)
310
            begin
311
             mdio_out_en = 1'b1;
312
             mdio_nxt_st = mdio_wrturn_st;
313
            end
314
            else
315
             begin
316
             mdio_out_en = 1'b0;
317
             mdio_nxt_st = mdio_rdturn_st;
318
             end
319
          end
320
 
321
        mdio_wrturn_st:
322
          // This state is used for write turn around
323
          begin
324
            mdio_out_en = 1'b1;
325
            mdio_out = 1'b0;
326
            mdio_nxt_st = mdio_write_st;
327
          end
328
 
329
        mdio_rdturn_st:
330
          // This state is used to read turn around state
331
          // the output enable is switched off
332
          begin
333
            if (mdio_in)
334
                set_mdio_stat = 1'b1;
335
            mdio_out_en = 1'b0;
336
            mdio_nxt_st = mdio_read_st;
337
          end
338
 
339
        mdio_write_st:
340
          // This state transfers the 16 bits of data to the
341
          // PHY
342
          begin
343
            mdio_out_en = 1'b1;
344
            write_data_mux_sel = 1'b1;
345
            if(inc_temp_count == SIXTEEN)
346
             begin
347
              reset_temp_count = 1'b1;
348
              mdio_out = transmit_data[15];
349
              mdio_nxt_st = mdio_complete_st;
350
             end
351
            else
352
             begin
353
              inc_count = 1'b1;
354
              mdio_out = transmit_data[15];
355
              mdio_nxt_st = mdio_write_st;
356
             end
357
          end
358
 
359
        mdio_read_st:
360
          // This state receives the 16 bits of data from the 
361
          // PHY
362
          begin
363
            mdio_out_en = 1'b0;
364
            read_data_mux_sel = 1'b1;
365
            if(inc_temp_count == SIXTEEN)
366
             begin
367
              reset_temp_count = 1'b1;
368
              mdio_nxt_st = mdio_complete_st;
369
             end
370
            else
371
             begin
372
              inc_count = 1'b1;
373
              mdio_nxt_st = mdio_read_st;
374
             end
375
          end
376
 
377
        mdio_complete_st:
378
          // This completes the mdio transfers indicates to the
379
          // application of such complete
380
          begin
381
            mdio_nxt_st = mdio_idle_st;
382
            mdio_out_en = 1'b0;
383
            read_data_mux_sel = 1'b0;
384
            //mdio_cmd_done = 1'b1;
385
//          mdio_stat = 1'b0;
386
          end
387
      endcase
388
   end
389
always @(mdio_cur_st)
390
 mdio_cmd_done  = (mdio_cur_st == 4'd13);
391
 
392
 
393
always @(posedge mdio_clk or negedge reset_n)
394
begin
395
    if (!reset_n)
396
      mdio_stat <= 1'b0;
397
    else if (set_mdio_stat)
398
      mdio_stat <= 1'b1;
399
    else if (clr_mdio_stat)
400
      mdio_stat <= 1'b0;
401
end
402
 
403
 
404
// This latches the PHY address, Register address and the
405
// Transmit data and the type of operation
406
//
407
 always @(posedge mdio_clk or negedge reset_n)
408
  begin
409
   if(!reset_n)
410
     begin
411
       phy_addr <= 5'd0;
412
       reg_addr <= 5'd0;
413
       transmit_data <= 16'd0;
414
       operation <= 1'b0;
415
       receive_data <= 16'd0;
416
     end
417
   else
418
     begin
419
       if(go_mdio_sync)
420
         begin
421
           phy_addr <= mdio_phyad;
422
           reg_addr <= mdio_regad;
423
           if(mdio_op == WRITE)
424
             begin
425
               operation <= 1'b1;
426
               transmit_data <= mdio_datain;
427
             end
428
         end
429
       else
430
         begin
431
           operation <= 1'b0;
432
           phy_addr <= phy_addr;
433
           transmit_data <= transmit_data;
434
           reg_addr <= reg_addr;
435
         //  receive_data <= receive_data; naveen 011299
436
         end // else: !if(go_mdio)
437
 
438
           if(phyaddr_mux_sel)
439
             begin
440
             /*
441
               phy_addr[0] <= phy_addr[1];
442
               phy_addr[1] <= phy_addr[2];
443
               phy_addr[2] <= phy_addr[3];
444
               phy_addr[3] <= phy_addr[4];
445
             */
446
               phy_addr[4] <= phy_addr[3];
447
               phy_addr[3] <= phy_addr[2];
448
               phy_addr[2] <= phy_addr[1];
449
               phy_addr[1] <= phy_addr[0];
450
             end
451
           if(regaddr_mux_sel)
452
             begin
453
               reg_addr[4] <= reg_addr[3];
454
               reg_addr[3] <= reg_addr[2];
455
               reg_addr[2] <= reg_addr[1];
456
               reg_addr[1] <= reg_addr[0];
457
             end
458
           if(write_data_mux_sel)
459
             begin
460
               transmit_data[15] <= transmit_data[14];
461
               transmit_data[14] <= transmit_data[13];
462
               transmit_data[13] <= transmit_data[12];
463
               transmit_data[12] <= transmit_data[11];
464
               transmit_data[11] <= transmit_data[10];
465
               transmit_data[10] <= transmit_data[9];
466
               transmit_data[9] <= transmit_data[8];
467
               transmit_data[8] <= transmit_data[7];
468
               transmit_data[7] <= transmit_data[6];
469
               transmit_data[6] <= transmit_data[5];
470
               transmit_data[5] <= transmit_data[4];
471
               transmit_data[4] <= transmit_data[3];
472
               transmit_data[3] <= transmit_data[2];
473
               transmit_data[2] <= transmit_data[1];
474
               transmit_data[1] <= transmit_data[0];
475
             end
476
           if(read_data_mux_sel)
477
             begin
478
               receive_data[0] <= mdio_in;
479
               receive_data[1] <= receive_data[0];
480
               receive_data[2] <= receive_data[1];
481
               receive_data[3] <= receive_data[2];
482
               receive_data[4] <= receive_data[3];
483
               receive_data[5] <= receive_data[4];
484
               receive_data[6] <= receive_data[5];
485
               receive_data[7] <= receive_data[6];
486
               receive_data[8] <= receive_data[7];
487
               receive_data[9] <= receive_data[8];
488
               receive_data[10] <= receive_data[9];
489
               receive_data[11] <= receive_data[10];
490
               receive_data[12] <= receive_data[11];
491
               receive_data[13] <= receive_data[12];
492
               receive_data[14] <= receive_data[13];
493
               receive_data[15] <= receive_data[14];
494
             end
495
        // end // else: !if(go_mdio) naveen 011298
496
     end // else: !if(!reset_n)
497
  end // always @ (posedge mdio_clk or negedge reset_n)
498
 
499
 // Temporary counter used to shift the data on the mdio line
500
 // This is also used to receive data on the line
501
 assign inc_temp_count = temp_count + 5'h1;
502
 
503
 always @(posedge mdio_clk or negedge reset_n)
504
   begin
505
     if(!reset_n)
506
        mdio_cur_st <= mdio_idle_st;
507
     else
508
        mdio_cur_st <= mdio_nxt_st;
509
   end // always @ (posedge mdio_clk or negedge reset_n)
510
 
511
   reg  mdio_outen_reg, mdio_out_reg;
512
 
513
  //----------------------------------------------
514
  // Scan fix done for negedge FF-Dinesh-A for A200
515
  // Note: Druring Scan Mode inverted mdio_clk used for 
516
  // mdio_outen_reg & mdio_out_reg
517
  //----------------------------------------------- 
518
  wire mdio_clk_scan = (scan_mode) ? !mdio_clk : mdio_clk;
519
 
520
   always @(negedge mdio_clk_scan or negedge reset_n)
521
   begin
522
     if(!reset_n)
523
     begin
524
        mdio_outen_reg <= 1'b0;
525
        mdio_out_reg <= 1'b0;
526
     end
527
     else
528
     begin
529
        mdio_outen_reg <= mdio_out_en;
530
        mdio_out_reg <= mdio_out;
531
     end
532
 
533
   end // always @ (posedge mdio_clk or negedge reset_n)
534
 
535
 always @(posedge mdio_clk or negedge reset_n)
536
   begin
537
     if(!reset_n)
538
        temp_count <= 5'b0;
539
     else
540
       begin
541
         if(reset_temp_count)
542
           temp_count <= 5'b0;
543
         else if(inc_count)
544
           temp_count <= inc_temp_count;
545
       end // else: !if(reset_n)
546
   end // always @ (posedge mdio_clk or negedge reset_n)
547
 
548
 
549
 
550
endmodule
551
 
552
 

powered by: WebSVN 2.1.0

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