aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/top/x300/gige_phy_mdio.v
blob: a86fee44792bf4f6008941cc67cc9100399a6672 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
module gige_phy_mdio
  (input reset, 
   input independent_clock,
   input sfp_clk,
   input SFP_RX_p, 
   input SFP_RX_n,
   output SFP_TX_p, 
   output SFP_TX_n,
   output gmii_clk,
   input  [7:0] gmii_txd, 
   input gmii_tx_en, 
   input gmii_tx_er,
   output [7:0] gmii_rxd, 
   output gmii_rx_dv, 
   output gmii_rx_er,
   output [31:0] misc_debug,
   output [15:0] int_data,
   output [15:0] status_vector,
   // MDIO signals
   input [4:0] prtad,
   input mdc,
   input mdio_i,
   output mdio_o,
   output mdio_t
   );


   wire   mmcm_locked, mmcm_reset, resetdone, clkfbout;
   wire   userclk, userclk2;
   wire   txoutclk, txoutclk_bufg;
   
   assign gmii_clk = userclk2; // 125 MHz
   
   // Route txoutclk input through a BUFG
   // FIXME is this really necessary?  It seems wasteful.
   BUFG  bufg_txoutclk (.I (txoutclk), .O (txoutclk_bufg));

   // This 62.5MHz clock is placed onto global clock routing and is then used
   // for tranceiver TXUSRCLK/RXUSRCLK.
   BUFG bufg_userclk (.I (clkout1), .O (userclk));

   // This 125MHz clock is placed onto global clock routing and is then used
   // to clock all Ethernet core logic.
   BUFG bufg_userclk2 (.I (clkout0), .O (userclk2));

   // The GT transceiver provides a 62.5MHz clock to the FPGA fabric.  This is 
   // routed to an MMCM module where it is used to create phase and frequency
   // related 62.5MHz and 125MHz clock sources
   MMCME2_ADV # 
     (.BANDWIDTH            ("OPTIMIZED"),
      .CLKOUT4_CASCADE      ("FALSE"),
      .COMPENSATION         ("ZHOLD"),
      .STARTUP_WAIT         ("FALSE"),
      .DIVCLK_DIVIDE        (1),
      .CLKFBOUT_MULT_F      (16.000),
      .CLKFBOUT_PHASE       (0.000),
      .CLKFBOUT_USE_FINE_PS ("FALSE"),
      .CLKOUT0_DIVIDE_F     (8.000),
      .CLKOUT0_PHASE        (0.000),
      .CLKOUT0_DUTY_CYCLE   (0.5),
      .CLKOUT0_USE_FINE_PS  ("FALSE"),
      .CLKOUT1_DIVIDE       (16),
      .CLKOUT1_PHASE        (0.000),
      .CLKOUT1_DUTY_CYCLE   (0.5),
      .CLKOUT1_USE_FINE_PS  ("FALSE"),
      .CLKIN1_PERIOD        (16.0),
      .REF_JITTER1          (0.010)
      ) mmcm_adv_inst 
       (// Output clocks
	.CLKFBOUT             (clkfbout),
	.CLKFBOUTB            (),
	.CLKOUT0              (clkout0),
	.CLKOUT0B             (),
	.CLKOUT1              (clkout1),
	.CLKOUT1B             (),
	.CLKOUT2              (),
	.CLKOUT2B             (),
	.CLKOUT3              (),
	.CLKOUT3B             (),
	.CLKOUT4              (),
	.CLKOUT5              (),
	.CLKOUT6              (),
	// Input clock control
	.CLKFBIN              (clkfbout),
	.CLKIN1               (txoutclk_bufg),
	.CLKIN2               (1'b0),
	// Tied to always select the primary input clock
	.CLKINSEL             (1'b1),
	// Ports for dynamic reconfiguration
	.DADDR                (7'h0),
	.DCLK                 (1'b0),
	.DEN                  (1'b0),
	.DI                   (16'h0),
	.DO                   (),
	.DRDY                 (),
	.DWE                  (1'b0),
	// Ports for dynamic phase shift
	.PSCLK                (1'b0),
	.PSEN                 (1'b0),
	.PSINCDEC             (1'b0),
	.PSDONE               (),
	// Other control and status signals
	.LOCKED               (mmcm_locked),
	.CLKINSTOPPED         (),
	.CLKFBSTOPPED         (),
	.PWRDWN               (1'b0),
	.RST                  (mmcm_reset)
	);

   assign mmcm_reset = reset | ~resetdone;


   gige_sfp_mdio_block gige_sfp_mdio_block 
     (
      .gtrefclk              (sfp_clk),
      .txp                   (SFP_TX_p),
      .txn                   (SFP_TX_n),
      .rxp                   (SFP_RX_p),
      .rxn                   (SFP_RX_n),
      .txoutclk              (txoutclk),
      .resetdone             (resetdone),
      .mmcm_locked           (mmcm_locked),
      .userclk               (userclk),
      .userclk2              (userclk2),
      .independent_clock_bufg(independent_clock),
      .pma_reset             (reset),
      .gmii_txd              (gmii_txd),
      .gmii_tx_en            (gmii_tx_en),
      .gmii_tx_er            (gmii_tx_er),
      .gmii_rxd              (gmii_rxd),
      .gmii_rx_dv            (gmii_rx_dv),
      .gmii_rx_er            (gmii_rx_er),
      .gmii_isolate          (), // Unused
      .mdc                   (mdc),
      .mdio_i                (mdio_i),
      .mdio_o                (mdio_o),
      .mdio_t                (mdio_t),
      .phyad                 (prtad),
      .configuration_vector  (5'b00000),
      .configuration_valid   (1'b1), //default
      .status_vector         (status_vector),
      .reset                 (reset),
      .signal_detect         (1'b1)
      );


endmodule // gige_phy