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 52

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

powered by: WebSVN 2.1.0

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