Skip to content

Commit f87d7fb

Browse files
committed
gmii to rgmii converter
1 parent e7a8d7a commit f87d7fb

File tree

1 file changed

+170
-0
lines changed

1 file changed

+170
-0
lines changed

rtl/gmii_to_rgmii.v

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
// cspell:ignore gmii, rgmii, posedge, IODDR, IODDR2, Virtex, BUFG, BUFR, Ultrascale, ALTERA
2+
/*
3+
4+
Converts gmii to rgmii and vice versa.
5+
6+
*/
7+
8+
`timescale 1ns / 1ps
9+
10+
module gmii_to_rgmii #
11+
(
12+
// target ("SIM", "GENERIC", "XILINX", "ALTERA")
13+
parameter TARGET = "GENERIC",
14+
// IODDR style ("IODDR", "IODDR2")
15+
// Use IODDR for Virtex-4, Virtex-5, Virtex-6, 7 Series, Ultrascale
16+
// Use IODDR2 for Spartan-6
17+
parameter IODDR_STYLE = "IODDR",
18+
// Clock input style ("BUFG", "BUFR", "BUFIO", "BUFIO2")
19+
// Use BUFR for Virtex-6, 7-series
20+
// Use BUFG for Virtex-5, Spartan-6, Ultrascale
21+
parameter CLOCK_INPUT_STYLE = "BUFG",
22+
// Use 90 degree clock for RGMII transmit ("TRUE", "FALSE")
23+
parameter USE_CLK90 = "TRUE"
24+
)
25+
(
26+
input wire clk,
27+
input wire clk90,
28+
input wire rst,
29+
30+
/*
31+
* GMII interface to MAC
32+
*/
33+
// Tx
34+
output wire mac_gmii_tx_clk,
35+
output wire mac_gmii_tx_rst,
36+
output wire mac_gmii_tx_clk_en,
37+
input wire [7:0] mac_gmii_txd,
38+
input wire mac_gmii_tx_en,
39+
input wire mac_gmii_tx_er,
40+
// Rx
41+
output wire mac_gmii_rx_clk,
42+
output wire mac_gmii_rx_rst,
43+
output wire [7:0] mac_gmii_rxd,
44+
output wire mac_gmii_rx_dv,
45+
output wire mac_gmii_rx_er,
46+
/*
47+
* RGMII interface to PHY
48+
*/
49+
// Tx
50+
output wire phy_rgmii_tx_clk,
51+
output wire [3:0] phy_rgmii_txd,
52+
output wire phy_rgmii_tx_ctl,
53+
// Rx
54+
input wire phy_rgmii_rx_clk,
55+
input wire [3:0] phy_rgmii_rxd,
56+
input wire phy_rgmii_rx_ctl,
57+
58+
);
59+
60+
61+
reg [1:0] speed_reg = 2'b10;
62+
reg mii_select_reg = 1'b0;
63+
64+
(* srl_style = "register" *)
65+
reg [1:0] tx_mii_select_sync = 2'd0;
66+
67+
always @(posedge mac_gmii_tx_clk) begin
68+
tx_mii_select_sync <= {tx_mii_select_sync[0], mii_select_reg};
69+
end
70+
71+
(* srl_style = "register" *)
72+
reg [1:0] rx_mii_select_sync = 2'd0;
73+
74+
always @(posedge mac_gmii_tx_clk) begin
75+
rx_mii_select_sync <= {rx_mii_select_sync[0], mii_select_reg};
76+
end
77+
78+
// PHY speed detection
79+
reg [2:0] rx_prescale = 3'd0;
80+
81+
always @(posedge mac_gmii_tx_clk) begin
82+
rx_prescale <= rx_prescale + 3'd1;
83+
end
84+
85+
(* srl_style = "register" *)
86+
reg [2:0] rx_prescale_sync = 3'd0;
87+
88+
always @(posedge phy_rgmii_tx_clk) begin
89+
rx_prescale_sync <= {rx_prescale_sync[1:0], rx_prescale[2]};
90+
end
91+
92+
reg [6:0] rx_speed_count_1 = 0;
93+
reg [1:0] rx_speed_count_2 = 0;
94+
95+
always @(posedge phy_rgmii_tx_clk) begin
96+
if (mac_gmii_tx_rst) begin
97+
rx_speed_count_1 <= 0;
98+
rx_speed_count_2 <= 0;
99+
speed_reg <= 2'b10;
100+
mii_select_reg <= 1'b0;
101+
end else begin
102+
rx_speed_count_1 <= rx_speed_count_1 + 1;
103+
104+
if (rx_prescale_sync[1] ^ rx_prescale_sync[2]) begin
105+
rx_speed_count_2 <= rx_speed_count_2 + 1;
106+
end
107+
108+
if (&rx_speed_count_1) begin
109+
// reference count overflow - 10M
110+
rx_speed_count_1 <= 0;
111+
rx_speed_count_2 <= 0;
112+
speed_reg <= 2'b00;
113+
mii_select_reg <= 1'b1;
114+
end
115+
116+
if (&rx_speed_count_2) begin
117+
// prescaled count overflow - 100M or 1000M
118+
rx_speed_count_1 <= 0;
119+
rx_speed_count_2 <= 0;
120+
if (rx_speed_count_1[6:5]) begin
121+
// large reference count - 100M
122+
speed_reg <= 2'b01;
123+
mii_select_reg <= 1'b1;
124+
end else begin
125+
// small reference count - 1000M
126+
speed_reg <= 2'b10;
127+
mii_select_reg <= 1'b0;
128+
end
129+
end
130+
end
131+
end
132+
133+
assign speed = speed_reg;
134+
135+
rgmii_phy_if #(
136+
.TARGET(TARGET),
137+
.IODDR_STYLE(IODDR_STYLE),
138+
.CLOCK_INPUT_STYLE(CLOCK_INPUT_STYLE),
139+
.USE_CLK90(USE_CLK90)
140+
)
141+
rgmii_phy_if_inst (
142+
.clk(clk),
143+
.clk90(clk90),
144+
.rst(rst),
145+
146+
.mac_gmii_rx_clk(mac_gmii_rx_clk),
147+
.mac_gmii_rx_rst(mac_gmii_rx_rst),
148+
.mac_gmii_rxd(mac_gmii_rxd),
149+
.mac_gmii_rx_dv(mac_gmii_rx_dv),
150+
.mac_gmii_rx_er(mac_gmii_rx_er),
151+
.mac_gmii_tx_clk(mac_gmii_tx_clk),
152+
.mac_gmii_tx_rst(mac_gmii_tx_rst),
153+
.mac_gmii_tx_clk_en(mac_gmii_tx_clk_en),
154+
.mac_gmii_txd(mac_gmii_txd),
155+
.mac_gmii_tx_en(mac_gmii_tx_en),
156+
.mac_gmii_tx_er(mac_gmii_tx_er),
157+
158+
.phy_rgmii_rx_clk(phy_rgmii_rx_clk),
159+
.phy_rgmii_rxd(phy_rgmii_rxd),
160+
.phy_rgmii_rx_ctl(phy_rgmii_rx_ctl),
161+
.phy_rgmii_tx_clk(phy_rgmii_tx_clk),
162+
.phy_rgmii_txd(phy_rgmii_txd),
163+
.phy_rgmii_tx_ctl(phy_rgmii_tx_ctl),
164+
165+
.speed(speed)
166+
);
167+
168+
169+
endmodule
170+

0 commit comments

Comments
 (0)