33// ------------------------------------
44// eth_gtx_hook.v
55// ------------------------------------
6+ // Converts between an internal/virtual GMII Ethernet port (8-bit, 125 MHz)
7+ // and the user pins of an on-chip serdes
8+ // GTX_DW = 10 : 125 MHz serdes clk for Spartan-6 LXT
9+ // GTX_DW = 20 DOUBLEBIT = 0 : 62.5 MHz serdes clk for Xilinx 7-series
10+ // GTX_DW = 20 DOUBLEBIT = 1 : 125 MHz serdes clk for Xilinx 7-series (experimental)
611
712module eth_gtx_hook #(
8- // JUMBO_DW Not used, just holdover for compatibility with older eth_gtx_bridge
9- parameter JUMBO_DW = 14 ,
13+ parameter JUMBO_DW = 14 , // Not used, just holdover for compatibility with older eth_gtx_bridge
1014 parameter EVENINIT = 0 ,
1115 parameter ENC_DISPINIT= 1'b0 ,
12- // GTX_DW Parallel GTX data width; Supported values are 10b and 20b
13- parameter GTX_DW = 20 ,
14- parameter CTRACE_AW = 14
15- ) (
16- input gtx_tx_clk, // Transceiver clock at half rate
16+ parameter GTX_DW = 20 , // Parallel GTX data width; Supported values are 10b and 20b
17+ parameter DOUBLEBIT = 0 ) // Experimental
18+ (
19+ input gtx_tx_clk, // Transceiver clock, sometimes at half rate
1720 input gmii_tx_clk, // Clock for Ethernet fabric - 125 MHz for 1GbE
1821 input gmii_rx_clk,
1922 input [GTX_DW- 1 :0 ] gtx_rxd,
@@ -42,20 +45,44 @@ module eth_gtx_hook #(
4245`endif
4346 );
4447
45- wire [9 :0 ] gtx_txd_10;
48+ wire [9 :0 ] gtx_txd_10; // driven by i_gmii_link
49+ wire [9 :0 ] gtx_rxd_10; // input to i_gmii_link
4650
4751 // ----------------------------------
4852 // Data width and rate conversion
4953 // ---------------------------------
5054
51- wire [9 :0 ] gtx_rxd_10;
52-
53- generate if (GTX_DW== 20 ) begin : G_GTX_DATA_CONV
54-
55+ generate if ((GTX_DW== 20 ) && DOUBLEBIT) begin : G_GTX_DOUBLEBIT_CONV
56+
57+ // gmii and gtx clocks are considered the same in this stanza
58+ // One could also write this bit rearrangement with a generate loop,
59+ // but I don't mind being explicit about it.
60+ assign gtx_txd = {
61+ gtx_txd_10[9 ], gtx_txd_10[9 ], gtx_txd_10[8 ], gtx_txd_10[8 ],
62+ gtx_txd_10[7 ], gtx_txd_10[7 ], gtx_txd_10[6 ], gtx_txd_10[6 ],
63+ gtx_txd_10[5 ], gtx_txd_10[5 ], gtx_txd_10[4 ], gtx_txd_10[4 ],
64+ gtx_txd_10[3 ], gtx_txd_10[3 ], gtx_txd_10[2 ], gtx_txd_10[2 ],
65+ gtx_txd_10[1 ], gtx_txd_10[1 ], gtx_txd_10[0 ], gtx_txd_10[0 ]};
66+ assign gtx_rxd_10 = {
67+ gtx_rxd[19 ], gtx_rxd[17 ],
68+ gtx_rxd[15 ], gtx_rxd[13 ],
69+ gtx_rxd[11 ], gtx_rxd[9 ],
70+ gtx_rxd[7 ], gtx_rxd[5 ],
71+ gtx_rxd[3 ], gtx_rxd[1 ]};
72+ wire confused = // XXX how to read out this status bit in hardware?
73+ (gtx_rxd[19 ]^gtx_rxd[18 ]) | (gtx_rxd[17 ]^gtx_rxd[16 ]) |
74+ (gtx_rxd[15 ]^gtx_rxd[14 ]) | (gtx_rxd[13 ]^gtx_rxd[12 ]) |
75+ (gtx_rxd[11 ]^gtx_rxd[10 ]) | (gtx_rxd[9 ]^gtx_rxd[8 ]) |
76+ (gtx_rxd[7 ]^gtx_rxd[6 ]) | (gtx_rxd[5 ]^gtx_rxd[4 ]) |
77+ (gtx_rxd[3 ]^gtx_rxd[2 ]) | (gtx_rxd[1 ]^gtx_rxd[0 ]);
78+
79+ end else if (GTX_DW== 20 ) begin : G_GTX_DATA_CONV
80+
81+ // gtx clock is half the gmii clock rate in this stanza
5582 reg [9 :0 ] gtx_rxd_10_r= 0 ;
5683 reg [9 :0 ] gtx_txd_r= 0 ;
57- wire [9 :0 ] gtp_rxd_l = gtx_rxd[9 :0 ];
58- wire [9 :0 ] gtp_rxd_h = gtx_rxd[19 :10 ];
84+ wire [9 :0 ] gtx_rxd_l = gtx_rxd[9 :0 ];
85+ wire [9 :0 ] gtx_rxd_h = gtx_rxd[19 :10 ];
5986 reg [19 :0 ] gtx_txd_l= 0 ;
6087 reg even= EVENINIT;
6188
@@ -65,10 +92,16 @@ module eth_gtx_hook #(
6592
6693 always @(posedge gmii_rx_clk) begin
6794 even <= ~ even;
68- gtx_rxd_10_r <= even ? gtp_rxd_l : gtp_rxd_h;
95+ // This next line would be a CDC, except Vivado "knows" that
96+ // gmii_rx_clk and gtx_rx_clk are "related clocks".
97+ // Note that gtx_rx_clk is only implicit in this module:
98+ // it's the clock domain of the gtx_rxd input port.
99+ gtx_rxd_10_r <= even ? gtx_rxd_l : gtx_rxd_h;
69100 end
70101
71102 always @(posedge gtx_tx_clk) begin
103+ // This next line would be a CDC, except Vivado "knows" that
104+ // gtx_tx_clk and gmii_tx_clk are "related clocks".
72105 gtx_txd_l <= {gtx_txd_10, gtx_txd_r};
73106 end
74107
@@ -77,6 +110,7 @@ module eth_gtx_hook #(
77110
78111 end else begin
79112
113+ // gmii and gtx clocks are considered the same in this stanza
80114 assign gtx_txd = gtx_txd_10;
81115 assign gtx_rxd_10 = gtx_rxd;
82116
0 commit comments