1 | ////////////////////////////////////////////////////////////////////////////////// |
---|
2 | // Company: (C) Athree, 2009 |
---|
3 | // Engineer: Dmitry Rozhdestvenskiy |
---|
4 | // Email dmitry.rozhdestvenskiy@srisc.com dmitryr@a3.spb.ru divx4log@narod.ru |
---|
5 | // |
---|
6 | // Design Name: OpenCores 10/10 Ethernet combined with Altera MII->SGMII bridge |
---|
7 | // Module Name: eth_sgmii |
---|
8 | // Project Name: SPARC SoC single-core |
---|
9 | // |
---|
10 | // LICENSE: |
---|
11 | // This is a Free Hardware Design; you can redistribute it and/or |
---|
12 | // modify it under the terms of the GNU General Public License |
---|
13 | // version 2 as published by the Free Software Foundation. |
---|
14 | // The above named program is distributed in the hope that it will |
---|
15 | // be useful, but WITHOUT ANY WARRANTY; without even the implied |
---|
16 | // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
---|
17 | // See the GNU General Public License for more details. |
---|
18 | // |
---|
19 | ////////////////////////////////////////////////////////////////////////////////// |
---|
20 | module eth_sgmii ( |
---|
21 | input wb_clk_i, |
---|
22 | input wb_rst_i, |
---|
23 | input sysclk, |
---|
24 | |
---|
25 | input [63:0] wb_dat_i, |
---|
26 | output [63:0] wb_dat_o, |
---|
27 | input [63:0] wb_adr_i, |
---|
28 | input [ 7:0] wb_sel_i, |
---|
29 | input wb_we_i, |
---|
30 | input wb_cyc_i, |
---|
31 | input wb_stb_i, |
---|
32 | output wb_ack_o, |
---|
33 | output wb_err_o, |
---|
34 | |
---|
35 | output [63:0] m_wb_adr_o, |
---|
36 | output [ 7:0] m_wb_sel_o, |
---|
37 | output m_wb_we_o, |
---|
38 | output [63:0] m_wb_dat_o, |
---|
39 | input [63:0] m_wb_dat_i, |
---|
40 | output m_wb_cyc_o, |
---|
41 | output m_wb_stb_o, |
---|
42 | input m_wb_ack_i, |
---|
43 | input m_wb_err_i, |
---|
44 | |
---|
45 | input sgmii_rx, |
---|
46 | output sgmii_tx, |
---|
47 | |
---|
48 | output int_eth, |
---|
49 | |
---|
50 | output led_10, |
---|
51 | output led_100, |
---|
52 | output led_1000, |
---|
53 | output led_an, |
---|
54 | output led_disp_err, |
---|
55 | output led_char_err, |
---|
56 | output led_link, |
---|
57 | |
---|
58 | inout md, |
---|
59 | output mdc |
---|
60 | ); |
---|
61 | |
---|
62 | wire [ 3:0] mrxd; |
---|
63 | wire [ 3:0] mtxd; |
---|
64 | wire [31:0] dat_o; |
---|
65 | wire [ 3:0] sel_o; |
---|
66 | wire [31:0] mdat_o; |
---|
67 | |
---|
68 | assign wb_dat_o={dat_o[7:0],dat_o[15:8],dat_o[23:16],dat_o[31:24],dat_o[7:0],dat_o[15:8],dat_o[23:16],dat_o[31:24]}; |
---|
69 | assign m_wb_adr_o[63:32]=0; |
---|
70 | assign m_wb_sel_o=m_wb_adr_o[2] ? {4'b0000,sel_o[0],sel_o[1],sel_o[2],sel_o[3]}:{sel_o[0],sel_o[1],sel_o[2],sel_o[3],4'b0000}; |
---|
71 | assign m_wb_dat_o={mdat_o[7:0],mdat_o[15:8],mdat_o[23:16],mdat_o[31:24],mdat_o[7:0],mdat_o[15:8],mdat_o[23:16],mdat_o[31:24]}; |
---|
72 | |
---|
73 | // OpenCores 10/100 Ethernet MAC |
---|
74 | eth_top eth_mac ( |
---|
75 | .wb_clk_i(wb_clk_i), |
---|
76 | .wb_rst_i(wb_rst_i), |
---|
77 | |
---|
78 | .wb_dat_i(wb_sel_i[7:4]==4'b0 ? {wb_dat_i[7:0],wb_dat_i[15:8],wb_dat_i[23:16],wb_dat_i[31:24]}:{wb_dat_i[39:32],wb_dat_i[47:40],wb_dat_i[55:48],wb_dat_i[63:56]}), |
---|
79 | .wb_dat_o(dat_o), |
---|
80 | .wb_adr_i(wb_adr_i[31:0]), |
---|
81 | .wb_sel_i(wb_sel_i[7:4]==4'b0 ? {wb_sel_i[0],wb_sel_i[1],wb_sel_i[2],wb_sel_i[3]}:{wb_sel_i[4],wb_sel_i[5],wb_sel_i[6],wb_sel_i[7]}), |
---|
82 | .wb_we_i(wb_we_i), |
---|
83 | .wb_cyc_i(wb_cyc_i), |
---|
84 | .wb_stb_i(wb_stb_i), |
---|
85 | .wb_ack_o(wb_ack_o), |
---|
86 | .wb_err_o(wb_err_o), |
---|
87 | .m_wb_adr_o(m_wb_adr_o[31:0]), |
---|
88 | .m_wb_sel_o(sel_o), |
---|
89 | .m_wb_we_o(m_wb_we_o), |
---|
90 | .m_wb_dat_o(mdat_o), |
---|
91 | .m_wb_dat_i(m_wb_adr_o[2] ? {m_wb_dat_i[7:0],m_wb_dat_i[15:8],m_wb_dat_i[23:16],m_wb_dat_i[31:24]}:{m_wb_dat_i[39:32],m_wb_dat_i[47:40],m_wb_dat_i[55:48],m_wb_dat_i[63:56]}), |
---|
92 | .m_wb_cyc_o(m_wb_cyc_o), |
---|
93 | .m_wb_stb_o(m_wb_stb_o), |
---|
94 | .m_wb_ack_i(m_wb_ack_i), |
---|
95 | .m_wb_err_i(m_wb_err_i), |
---|
96 | |
---|
97 | .mtx_clk_pad_i(mtx_clk), |
---|
98 | .mtxd_pad_o(mtxd), |
---|
99 | .mtxen_pad_o(mtxen), |
---|
100 | .mtxerr_pad_o(mtxerr), |
---|
101 | .mrx_clk_pad_i(mrx_clk), |
---|
102 | .mrxd_pad_i(mrxd), |
---|
103 | .mrxdv_pad_i(mrxdv), |
---|
104 | .mrxerr_pad_i(mrxerr), |
---|
105 | .mcoll_pad_i(mcoll), |
---|
106 | .mcrs_pad_i(mcrs), |
---|
107 | .mdc_pad_o(mdc), |
---|
108 | .md_pad_i(md_i), |
---|
109 | .md_pad_o(md_o), |
---|
110 | .md_padoe_o(md_oe), |
---|
111 | .int_o(int_eth) |
---|
112 | ); |
---|
113 | |
---|
114 | assign md_i=md; |
---|
115 | assign md=md_oe ? md_o:1'bZ; |
---|
116 | |
---|
117 | /*reg [63:0] mdio_shift; |
---|
118 | reg [ 5:0] mdio_cnt; |
---|
119 | wire [15:0] mdio_wrdata; |
---|
120 | wire [15:0] mdio_rdata; |
---|
121 | wire [ 4:0] mdio_addr; |
---|
122 | reg mdio_wr; |
---|
123 | |
---|
124 | assign mdio_rd=(mdio_cnt==6'd46) && mdio_shift[45:14]==32'hFFFFFFFF; // Address just latched, frame valid |
---|
125 | assign mdio_wrdata=mdio_shift[15:0]; |
---|
126 | assign md_i=mdio_rdata[~mdio_cnt+1]; |
---|
127 | assign mdio_addr=(mdio_cnt<6'd48) ? mdio_shift[4:0]:mdio_shift[22:18]; |
---|
128 | |
---|
129 | always @(posedge mdc or posedge wb_rst_i) |
---|
130 | if(wb_rst_i) |
---|
131 | begin |
---|
132 | mdio_cnt<=0; |
---|
133 | mdio_shift<=64'b0; |
---|
134 | end |
---|
135 | else |
---|
136 | begin |
---|
137 | mdio_shift[0]<=md_o; |
---|
138 | mdio_shift[63:1]<=mdio_shift[62:0]; |
---|
139 | mdio_cnt<=mdio_cnt+1; |
---|
140 | if(mdio_cnt==6'd63 && mdio_shift[62:27]==36'hFFFFFFFF5) |
---|
141 | mdio_wr<=1; |
---|
142 | else |
---|
143 | mdio_wr<=0; |
---|
144 | end*/ |
---|
145 | |
---|
146 | // Altera Ethernet controller in MII->SGMII bridge mode |
---|
147 | // You may generate it with Quartus use it for free in test mode |
---|
148 | // (either time-limited or connected to PC) |
---|
149 | MII2SGMII eth_pcs( |
---|
150 | .ref_clk(sysclk), |
---|
151 | .reset(wb_rst_i), |
---|
152 | |
---|
153 | .gmii_rx_d(), |
---|
154 | .gmii_rx_dv(), |
---|
155 | .gmii_rx_err(), |
---|
156 | .gmii_tx_d(0), |
---|
157 | .gmii_tx_en(0), |
---|
158 | .gmii_tx_err(0), |
---|
159 | |
---|
160 | .tx_clk(mtx_clk), |
---|
161 | .reset_tx_clk(wb_rst_i), |
---|
162 | .tx_clkena(), |
---|
163 | .mii_tx_d(mtxd), |
---|
164 | .mii_tx_en(mtxen), |
---|
165 | .mii_tx_err(mtxerr), |
---|
166 | |
---|
167 | .rx_clk(mrx_clk), |
---|
168 | .reset_rx_clk(wb_rst_i), |
---|
169 | .rx_clkena(), |
---|
170 | .mii_rx_d(mrxd), |
---|
171 | .mii_rx_dv(mrxdv), |
---|
172 | .mii_rx_err(mrxerr), |
---|
173 | .mii_col(mcoll), |
---|
174 | .mii_crs(mcrs), |
---|
175 | |
---|
176 | .set_10(led_10), |
---|
177 | .set_100(led_100), |
---|
178 | .set_1000(led_1000), |
---|
179 | |
---|
180 | .hd_ena(), |
---|
181 | |
---|
182 | .txp(sgmii_tx), |
---|
183 | .rxp(sgmii_rx), |
---|
184 | |
---|
185 | .led_col(), |
---|
186 | .led_crs(), |
---|
187 | .led_an(led_an), |
---|
188 | .led_disp_err(led_disp_err), |
---|
189 | .led_char_err(led_char_err), |
---|
190 | .led_link(led_link), |
---|
191 | |
---|
192 | .clk(0), |
---|
193 | .readdata(), |
---|
194 | .waitrequest(), |
---|
195 | .address(), |
---|
196 | .read(0), |
---|
197 | .writedata(), |
---|
198 | .write(0) |
---|
199 | ); |
---|
200 | |
---|
201 | endmodule |
---|