summaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/top/x300/gige_phy.v
blob: 685272b0504422e1911738744e5a9ecb4b2132fa (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
module gige_phy
  (input reset, 
   input independent_clock,
//   input ETH_CLK_p, input ETH_CLK_n,
   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);

//   wire   sfp_clk;
   wire   mmcm_locked, mmcm_reset, resetdone, clkfbout;
   wire   userclk, userclk2;
   wire   txoutclk, txoutclk_bufg;
   assign gmii_clk = userclk2; // 125 MHz
   
//   IBUFDS_GTE2 clk_sfp_pin (.O(sfp_clk),.I(ETH_CLK_p),.IB(ETH_CLK_n), .CEB(1'b0));

   // 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_block gige_sfp_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

      .configuration_vector(5'b00000),
      .status_vector(status_vector), .reset(reset), .signal_detect(1'b1),
      .misc_debug(misc_debug),
      .int_data(int_data));

endmodule // gige_phy