3
3
// ------------------------------------
4
4
// eth_gtx_hook.v
5
5
// ------------------------------------
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)
6
11
7
12
module eth_gtx_hook #(
8
- parameter JUMBO_DW = 14 , // Not used, just holdover for compatibility with older eth_gtx_bridge
13
+ parameter JUMBO_DW = 14 , // Not used, just holdover for compatibility with older eth_gtx_bridge
9
14
parameter EVENINIT = 0 ,
10
15
parameter ENC_DISPINIT= 1'b0 ,
11
- parameter GTX_DW = 20 ) // Parallel GTX data width; Supported values are 10b and 20b
16
+ parameter GTX_DW = 20 , // Parallel GTX data width; Supported values are 10b and 20b
17
+ parameter DOUBLEBIT = 0 ) // Experimental
12
18
(
13
- input gtx_tx_clk, // Transceiver clock at half rate
19
+ input gtx_tx_clk, // Transceiver clock, sometimes at half rate
14
20
input gmii_tx_clk, // Clock for Ethernet fabric - 125 MHz for 1GbE
15
21
input gmii_rx_clk,
16
22
input [GTX_DW- 1 :0 ] gtx_rxd,
@@ -29,20 +35,44 @@ module eth_gtx_hook #(
29
35
30
36
);
31
37
32
- wire [9 :0 ] gtx_txd_10;
38
+ wire [9 :0 ] gtx_txd_10; // driven by i_gmii_link
39
+ wire [9 :0 ] gtx_rxd_10; // input to i_gmii_link
33
40
34
41
// ----------------------------------
35
42
// Data width and rate conversion
36
43
// ---------------------------------
37
44
38
- wire [9 :0 ] gtx_rxd_10;
39
-
40
- generate if (GTX_DW== 20 ) begin : G_GTX_DATA_CONV
41
-
45
+ generate if ((GTX_DW== 20 ) && DOUBLEBIT) begin : G_GTX_DOUBLEBIT_CONV
46
+
47
+ // gmii and gtx clocks are considered the same in this stanza
48
+ // One could also write this bit rearrangement with a generate loop,
49
+ // but I don't mind being explicit about it.
50
+ assign gtx_txd = {
51
+ gtx_txd_10[9 ], gtx_txd_10[9 ], gtx_txd_10[8 ], gtx_txd_10[8 ],
52
+ gtx_txd_10[7 ], gtx_txd_10[7 ], gtx_txd_10[6 ], gtx_txd_10[6 ],
53
+ gtx_txd_10[5 ], gtx_txd_10[5 ], gtx_txd_10[4 ], gtx_txd_10[4 ],
54
+ gtx_txd_10[3 ], gtx_txd_10[3 ], gtx_txd_10[2 ], gtx_txd_10[2 ],
55
+ gtx_txd_10[1 ], gtx_txd_10[1 ], gtx_txd_10[0 ], gtx_txd_10[0 ]};
56
+ assign gtx_rxd_10 = {
57
+ gtx_rxd[19 ], gtx_rxd[17 ],
58
+ gtx_rxd[15 ], gtx_rxd[13 ],
59
+ gtx_rxd[11 ], gtx_rxd[9 ],
60
+ gtx_rxd[7 ], gtx_rxd[5 ],
61
+ gtx_rxd[3 ], gtx_rxd[1 ]};
62
+ wire confused = // XXX how to read out this status bit in hardware?
63
+ (gtx_rxd[19 ]^gtx_rxd[18 ]) | (gtx_rxd[17 ]^gtx_rxd[16 ]) |
64
+ (gtx_rxd[15 ]^gtx_rxd[14 ]) | (gtx_rxd[13 ]^gtx_rxd[12 ]) |
65
+ (gtx_rxd[11 ]^gtx_rxd[10 ]) | (gtx_rxd[9 ]^gtx_rxd[8 ]) |
66
+ (gtx_rxd[7 ]^gtx_rxd[6 ]) | (gtx_rxd[5 ]^gtx_rxd[4 ]) |
67
+ (gtx_rxd[3 ]^gtx_rxd[2 ]) | (gtx_rxd[1 ]^gtx_rxd[0 ]);
68
+
69
+ end else if (GTX_DW== 20 ) begin : G_GTX_DATA_CONV
70
+
71
+ // gtx clock is half the gmii clock rate in this stanza
42
72
reg [9 :0 ] gtx_rxd_10_r= 0 ;
43
73
reg [9 :0 ] gtx_txd_r= 0 ;
44
- wire [9 :0 ] gtp_rxd_l = gtx_rxd[9 :0 ];
45
- wire [9 :0 ] gtp_rxd_h = gtx_rxd[19 :10 ];
74
+ wire [9 :0 ] gtx_rxd_l = gtx_rxd[9 :0 ];
75
+ wire [9 :0 ] gtx_rxd_h = gtx_rxd[19 :10 ];
46
76
reg [19 :0 ] gtx_txd_l= 0 ;
47
77
reg even= EVENINIT;
48
78
@@ -52,10 +82,16 @@ module eth_gtx_hook #(
52
82
53
83
always @(posedge gmii_rx_clk) begin
54
84
even <= ~ even;
55
- gtx_rxd_10_r <= even ? gtp_rxd_l : gtp_rxd_h;
85
+ // This next line would be a CDC, except Vivado "knows" that
86
+ // gmii_rx_clk and gtx_rx_clk are "related clocks".
87
+ // Note that gtx_rx_clk is only implicit in this module:
88
+ // it's the clock domain of the gtx_rxd input port.
89
+ gtx_rxd_10_r <= even ? gtx_rxd_l : gtx_rxd_h;
56
90
end
57
91
58
92
always @(posedge gtx_tx_clk) begin
93
+ // This next line would be a CDC, except Vivado "knows" that
94
+ // gtx_tx_clk and gmii_tx_clk are "related clocks".
59
95
gtx_txd_l <= {gtx_txd_10, gtx_txd_r};
60
96
end
61
97
@@ -64,6 +100,7 @@ module eth_gtx_hook #(
64
100
65
101
end else begin
66
102
103
+ // gmii and gtx clocks are considered the same in this stanza
67
104
assign gtx_txd = gtx_txd_10;
68
105
assign gtx_rxd_10 = gtx_rxd;
69
106
0 commit comments