]>
Commit | Line | Data |
---|---|---|
40a1f26c | 1 | ////////////////////////////////////////////////////////////////////// |
2 | //// //// | |
3 | //// eth_cop.v //// | |
4 | //// //// | |
5 | //// This file is part of the Ethernet IP core project //// | |
6 | //// http://www.opencores.org/projects/ethmac/ //// | |
7 | //// //// | |
8 | //// Author(s): //// | |
9 | //// - Igor Mohor (igorM@opencores.org) //// | |
10 | //// //// | |
11 | //// All additional information is avaliable in the Readme.txt //// | |
12 | //// file. //// | |
13 | //// //// | |
14 | ////////////////////////////////////////////////////////////////////// | |
15 | //// //// | |
16 | //// Copyright (C) 2001, 2002 Authors //// | |
17 | //// //// | |
18 | //// This source file may be used and distributed without //// | |
19 | //// restriction provided that this copyright statement is not //// | |
20 | //// removed from the file and that any derivative work contains //// | |
21 | //// the original copyright notice and the associated disclaimer. //// | |
22 | //// //// | |
23 | //// This source file is free software; you can redistribute it //// | |
24 | //// and/or modify it under the terms of the GNU Lesser General //// | |
25 | //// Public License as published by the Free Software Foundation; //// | |
26 | //// either version 2.1 of the License, or (at your option) any //// | |
27 | //// later version. //// | |
28 | //// //// | |
29 | //// This source is distributed in the hope that it will be //// | |
30 | //// useful, but WITHOUT ANY WARRANTY; without even the implied //// | |
31 | //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// | |
32 | //// PURPOSE. See the GNU Lesser General Public License for more //// | |
33 | //// details. //// | |
34 | //// //// | |
35 | //// You should have received a copy of the GNU Lesser General //// | |
36 | //// Public License along with this source; if not, download it //// | |
37 | //// from http://www.opencores.org/lgpl.shtml //// | |
38 | //// //// | |
39 | ////////////////////////////////////////////////////////////////////// | |
40 | // | |
41 | // CVS Revision History | |
42 | // | |
43 | // $Log: eth_cop.v,v $ | |
44 | // Revision 1.1 2007-03-20 17:50:56 sithglan | |
45 | // add shit | |
46 | // | |
47 | // Revision 1.4 2003/06/13 11:55:37 mohor | |
48 | // Define file in eth_cop.v is changed to eth_defines.v. Some defines were | |
49 | // moved from tb_eth_defines.v to eth_defines.v. | |
50 | // | |
51 | // Revision 1.3 2002/10/10 16:43:59 mohor | |
52 | // Minor $display change. | |
53 | // | |
54 | // Revision 1.2 2002/09/09 12:54:13 mohor | |
55 | // error acknowledge cycle termination added to display. | |
56 | // | |
57 | // Revision 1.1 2002/08/14 17:16:07 mohor | |
58 | // Traffic cop with 2 wishbone master interfaces and 2 wishbona slave | |
59 | // interfaces: | |
60 | // - Host connects to the master interface | |
61 | // - Ethernet master (DMA) connects to the second master interface | |
62 | // - Memory interface connects to the slave interface | |
63 | // - Ethernet slave interface (access to registers and BDs) connects to second | |
64 | // slave interface | |
65 | // | |
66 | // | |
67 | // | |
68 | // | |
69 | // | |
70 | ||
71 | `include "eth_defines.v" | |
72 | `include "timescale.v" | |
73 | ||
74 | module eth_cop | |
75 | ( | |
76 | // WISHBONE common | |
77 | wb_clk_i, wb_rst_i, | |
78 | ||
79 | // WISHBONE MASTER 1 | |
80 | m1_wb_adr_i, m1_wb_sel_i, m1_wb_we_i, m1_wb_dat_o, | |
81 | m1_wb_dat_i, m1_wb_cyc_i, m1_wb_stb_i, m1_wb_ack_o, | |
82 | m1_wb_err_o, | |
83 | ||
84 | // WISHBONE MASTER 2 | |
85 | m2_wb_adr_i, m2_wb_sel_i, m2_wb_we_i, m2_wb_dat_o, | |
86 | m2_wb_dat_i, m2_wb_cyc_i, m2_wb_stb_i, m2_wb_ack_o, | |
87 | m2_wb_err_o, | |
88 | ||
89 | // WISHBONE slave 1 | |
90 | s1_wb_adr_o, s1_wb_sel_o, s1_wb_we_o, s1_wb_cyc_o, | |
91 | s1_wb_stb_o, s1_wb_ack_i, s1_wb_err_i, s1_wb_dat_i, | |
92 | s1_wb_dat_o, | |
93 | ||
94 | // WISHBONE slave 2 | |
95 | s2_wb_adr_o, s2_wb_sel_o, s2_wb_we_o, s2_wb_cyc_o, | |
96 | s2_wb_stb_o, s2_wb_ack_i, s2_wb_err_i, s2_wb_dat_i, | |
97 | s2_wb_dat_o | |
98 | ); | |
99 | ||
100 | parameter Tp=1; | |
101 | ||
102 | // WISHBONE common | |
103 | input wb_clk_i, wb_rst_i; | |
104 | ||
105 | // WISHBONE MASTER 1 | |
106 | input [31:0] m1_wb_adr_i, m1_wb_dat_i; | |
107 | input [3:0] m1_wb_sel_i; | |
108 | input m1_wb_cyc_i, m1_wb_stb_i, m1_wb_we_i; | |
109 | output [31:0] m1_wb_dat_o; | |
110 | output m1_wb_ack_o, m1_wb_err_o; | |
111 | ||
112 | // WISHBONE MASTER 2 | |
113 | input [31:0] m2_wb_adr_i, m2_wb_dat_i; | |
114 | input [3:0] m2_wb_sel_i; | |
115 | input m2_wb_cyc_i, m2_wb_stb_i, m2_wb_we_i; | |
116 | output [31:0] m2_wb_dat_o; | |
117 | output m2_wb_ack_o, m2_wb_err_o; | |
118 | ||
119 | // WISHBONE slave 1 | |
120 | input [31:0] s1_wb_dat_i; | |
121 | input s1_wb_ack_i, s1_wb_err_i; | |
122 | output [31:0] s1_wb_adr_o, s1_wb_dat_o; | |
123 | output [3:0] s1_wb_sel_o; | |
124 | output s1_wb_we_o, s1_wb_cyc_o, s1_wb_stb_o; | |
125 | ||
126 | // WISHBONE slave 2 | |
127 | input [31:0] s2_wb_dat_i; | |
128 | input s2_wb_ack_i, s2_wb_err_i; | |
129 | output [31:0] s2_wb_adr_o, s2_wb_dat_o; | |
130 | output [3:0] s2_wb_sel_o; | |
131 | output s2_wb_we_o, s2_wb_cyc_o, s2_wb_stb_o; | |
132 | ||
133 | reg m1_in_progress; | |
134 | reg m2_in_progress; | |
135 | reg [31:0] s1_wb_adr_o; | |
136 | reg [3:0] s1_wb_sel_o; | |
137 | reg s1_wb_we_o; | |
138 | reg [31:0] s1_wb_dat_o; | |
139 | reg s1_wb_cyc_o; | |
140 | reg s1_wb_stb_o; | |
141 | reg [31:0] s2_wb_adr_o; | |
142 | reg [3:0] s2_wb_sel_o; | |
143 | reg s2_wb_we_o; | |
144 | reg [31:0] s2_wb_dat_o; | |
145 | reg s2_wb_cyc_o; | |
146 | reg s2_wb_stb_o; | |
147 | ||
148 | reg m1_wb_ack_o; | |
149 | reg [31:0] m1_wb_dat_o; | |
150 | reg m2_wb_ack_o; | |
151 | reg [31:0] m2_wb_dat_o; | |
152 | ||
153 | reg m1_wb_err_o; | |
154 | reg m2_wb_err_o; | |
155 | ||
156 | wire m_wb_access_finished; | |
157 | wire m1_req = m1_wb_cyc_i & m1_wb_stb_i & (`M1_ADDRESSED_S1 | `M1_ADDRESSED_S2); | |
158 | wire m2_req = m2_wb_cyc_i & m2_wb_stb_i & (`M2_ADDRESSED_S1 | `M2_ADDRESSED_S2); | |
159 | ||
160 | always @ (posedge wb_clk_i or posedge wb_rst_i) | |
161 | begin | |
162 | if(wb_rst_i) | |
163 | begin | |
164 | m1_in_progress <=#Tp 0; | |
165 | m2_in_progress <=#Tp 0; | |
166 | s1_wb_adr_o <=#Tp 0; | |
167 | s1_wb_sel_o <=#Tp 0; | |
168 | s1_wb_we_o <=#Tp 0; | |
169 | s1_wb_dat_o <=#Tp 0; | |
170 | s1_wb_cyc_o <=#Tp 0; | |
171 | s1_wb_stb_o <=#Tp 0; | |
172 | s2_wb_adr_o <=#Tp 0; | |
173 | s2_wb_sel_o <=#Tp 0; | |
174 | s2_wb_we_o <=#Tp 0; | |
175 | s2_wb_dat_o <=#Tp 0; | |
176 | s2_wb_cyc_o <=#Tp 0; | |
177 | s2_wb_stb_o <=#Tp 0; | |
178 | end | |
179 | else | |
180 | begin | |
181 | case({m1_in_progress, m2_in_progress, m1_req, m2_req, m_wb_access_finished}) // synopsys_full_case synopsys_paralel_case | |
182 | 5'b00_10_0, 5'b00_11_0 : | |
183 | begin | |
184 | m1_in_progress <=#Tp 1'b1; // idle: m1 or (m1 & m2) want access: m1 -> m | |
185 | if(`M1_ADDRESSED_S1) | |
186 | begin | |
187 | s1_wb_adr_o <=#Tp m1_wb_adr_i; | |
188 | s1_wb_sel_o <=#Tp m1_wb_sel_i; | |
189 | s1_wb_we_o <=#Tp m1_wb_we_i; | |
190 | s1_wb_dat_o <=#Tp m1_wb_dat_i; | |
191 | s1_wb_cyc_o <=#Tp 1'b1; | |
192 | s1_wb_stb_o <=#Tp 1'b1; | |
193 | end | |
194 | else if(`M1_ADDRESSED_S2) | |
195 | begin | |
196 | s2_wb_adr_o <=#Tp m1_wb_adr_i; | |
197 | s2_wb_sel_o <=#Tp m1_wb_sel_i; | |
198 | s2_wb_we_o <=#Tp m1_wb_we_i; | |
199 | s2_wb_dat_o <=#Tp m1_wb_dat_i; | |
200 | s2_wb_cyc_o <=#Tp 1'b1; | |
201 | s2_wb_stb_o <=#Tp 1'b1; | |
202 | end | |
203 | else | |
204 | $display("(%t)(%m)WISHBONE ERROR: Unspecified address space accessed", $time); | |
205 | end | |
206 | 5'b00_01_0 : | |
207 | begin | |
208 | m2_in_progress <=#Tp 1'b1; // idle: m2 wants access: m2 -> m | |
209 | if(`M2_ADDRESSED_S1) | |
210 | begin | |
211 | s1_wb_adr_o <=#Tp m2_wb_adr_i; | |
212 | s1_wb_sel_o <=#Tp m2_wb_sel_i; | |
213 | s1_wb_we_o <=#Tp m2_wb_we_i; | |
214 | s1_wb_dat_o <=#Tp m2_wb_dat_i; | |
215 | s1_wb_cyc_o <=#Tp 1'b1; | |
216 | s1_wb_stb_o <=#Tp 1'b1; | |
217 | end | |
218 | else if(`M2_ADDRESSED_S2) | |
219 | begin | |
220 | s2_wb_adr_o <=#Tp m2_wb_adr_i; | |
221 | s2_wb_sel_o <=#Tp m2_wb_sel_i; | |
222 | s2_wb_we_o <=#Tp m2_wb_we_i; | |
223 | s2_wb_dat_o <=#Tp m2_wb_dat_i; | |
224 | s2_wb_cyc_o <=#Tp 1'b1; | |
225 | s2_wb_stb_o <=#Tp 1'b1; | |
226 | end | |
227 | else | |
228 | $display("(%t)(%m)WISHBONE ERROR: Unspecified address space accessed", $time); | |
229 | end | |
230 | 5'b10_10_1, 5'b10_11_1 : | |
231 | begin | |
232 | m1_in_progress <=#Tp 1'b0; // m1 in progress. Cycle is finished. Send ack or err to m1. | |
233 | if(`M1_ADDRESSED_S1) | |
234 | begin | |
235 | s1_wb_cyc_o <=#Tp 1'b0; | |
236 | s1_wb_stb_o <=#Tp 1'b0; | |
237 | end | |
238 | else if(`M1_ADDRESSED_S2) | |
239 | begin | |
240 | s2_wb_cyc_o <=#Tp 1'b0; | |
241 | s2_wb_stb_o <=#Tp 1'b0; | |
242 | end | |
243 | end | |
244 | 5'b01_01_1, 5'b01_11_1 : | |
245 | begin | |
246 | m2_in_progress <=#Tp 1'b0; // m2 in progress. Cycle is finished. Send ack or err to m2. | |
247 | if(`M2_ADDRESSED_S1) | |
248 | begin | |
249 | s1_wb_cyc_o <=#Tp 1'b0; | |
250 | s1_wb_stb_o <=#Tp 1'b0; | |
251 | end | |
252 | else if(`M2_ADDRESSED_S2) | |
253 | begin | |
254 | s2_wb_cyc_o <=#Tp 1'b0; | |
255 | s2_wb_stb_o <=#Tp 1'b0; | |
256 | end | |
257 | end | |
258 | endcase | |
259 | end | |
260 | end | |
261 | ||
262 | // Generating Ack for master 1 | |
263 | always @ (m1_in_progress or m1_wb_adr_i or s1_wb_ack_i or s2_wb_ack_i or s1_wb_dat_i or s2_wb_dat_i or `M1_ADDRESSED_S1 or `M1_ADDRESSED_S2) | |
264 | begin | |
265 | if(m1_in_progress) | |
266 | begin | |
267 | if(`M1_ADDRESSED_S1) begin | |
268 | m1_wb_ack_o <= s1_wb_ack_i; | |
269 | m1_wb_dat_o <= s1_wb_dat_i; | |
270 | end | |
271 | else if(`M1_ADDRESSED_S2) begin | |
272 | m1_wb_ack_o <= s2_wb_ack_i; | |
273 | m1_wb_dat_o <= s2_wb_dat_i; | |
274 | end | |
275 | end | |
276 | else | |
277 | m1_wb_ack_o <= 0; | |
278 | end | |
279 | ||
280 | ||
281 | // Generating Ack for master 2 | |
282 | always @ (m2_in_progress or m2_wb_adr_i or s1_wb_ack_i or s2_wb_ack_i or s1_wb_dat_i or s2_wb_dat_i or `M2_ADDRESSED_S1 or `M2_ADDRESSED_S2) | |
283 | begin | |
284 | if(m2_in_progress) | |
285 | begin | |
286 | if(`M2_ADDRESSED_S1) begin | |
287 | m2_wb_ack_o <= s1_wb_ack_i; | |
288 | m2_wb_dat_o <= s1_wb_dat_i; | |
289 | end | |
290 | else if(`M2_ADDRESSED_S2) begin | |
291 | m2_wb_ack_o <= s2_wb_ack_i; | |
292 | m2_wb_dat_o <= s2_wb_dat_i; | |
293 | end | |
294 | end | |
295 | else | |
296 | m2_wb_ack_o <= 0; | |
297 | end | |
298 | ||
299 | ||
300 | // Generating Err for master 1 | |
301 | always @ (m1_in_progress or m1_wb_adr_i or s1_wb_err_i or s2_wb_err_i or `M2_ADDRESSED_S1 or `M2_ADDRESSED_S2 or | |
302 | m1_wb_cyc_i or m1_wb_stb_i) | |
303 | begin | |
304 | if(m1_in_progress) begin | |
305 | if(`M1_ADDRESSED_S1) | |
306 | m1_wb_err_o <= s1_wb_err_i; | |
307 | else if(`M1_ADDRESSED_S2) | |
308 | m1_wb_err_o <= s2_wb_err_i; | |
309 | end | |
310 | else if(m1_wb_cyc_i & m1_wb_stb_i & ~`M1_ADDRESSED_S1 & ~`M1_ADDRESSED_S2) | |
311 | m1_wb_err_o <= 1'b1; | |
312 | else | |
313 | m1_wb_err_o <= 1'b0; | |
314 | end | |
315 | ||
316 | ||
317 | // Generating Err for master 2 | |
318 | always @ (m2_in_progress or m2_wb_adr_i or s1_wb_err_i or s2_wb_err_i or `M2_ADDRESSED_S1 or `M2_ADDRESSED_S2 or | |
319 | m2_wb_cyc_i or m2_wb_stb_i) | |
320 | begin | |
321 | if(m2_in_progress) begin | |
322 | if(`M2_ADDRESSED_S1) | |
323 | m2_wb_err_o <= s1_wb_err_i; | |
324 | else if(`M2_ADDRESSED_S2) | |
325 | m2_wb_err_o <= s2_wb_err_i; | |
326 | end | |
327 | else if(m2_wb_cyc_i & m2_wb_stb_i & ~`M2_ADDRESSED_S1 & ~`M2_ADDRESSED_S2) | |
328 | m2_wb_err_o <= 1'b1; | |
329 | else | |
330 | m2_wb_err_o <= 1'b0; | |
331 | end | |
332 | ||
333 | ||
334 | assign m_wb_access_finished = m1_wb_ack_o | m1_wb_err_o | m2_wb_ack_o | m2_wb_err_o; | |
335 | ||
336 | ||
337 | // Activity monitor | |
338 | integer cnt; | |
339 | always @ (posedge wb_clk_i or posedge wb_rst_i) | |
340 | begin | |
341 | if(wb_rst_i) | |
342 | cnt <=#Tp 0; | |
343 | else | |
344 | if(s1_wb_ack_i | s1_wb_err_i | s2_wb_ack_i | s2_wb_err_i) | |
345 | cnt <=#Tp 0; | |
346 | else | |
347 | if(s1_wb_cyc_o | s2_wb_cyc_o) | |
348 | cnt <=#Tp cnt+1; | |
349 | end | |
350 | ||
351 | always @ (posedge wb_clk_i) | |
352 | begin | |
353 | if(cnt==1000) begin | |
354 | $display("(%0t)(%m) ERROR: WB activity ??? ", $time); | |
355 | if(s1_wb_cyc_o) begin | |
356 | $display("s1_wb_dat_o = 0x%0x", s1_wb_dat_o); | |
357 | $display("s1_wb_adr_o = 0x%0x", s1_wb_adr_o); | |
358 | $display("s1_wb_sel_o = 0x%0x", s1_wb_sel_o); | |
359 | $display("s1_wb_we_o = 0x%0x", s1_wb_we_o); | |
360 | end | |
361 | else if(s2_wb_cyc_o) begin | |
362 | $display("s2_wb_dat_o = 0x%0x", s2_wb_dat_o); | |
363 | $display("s2_wb_adr_o = 0x%0x", s2_wb_adr_o); | |
364 | $display("s2_wb_sel_o = 0x%0x", s2_wb_sel_o); | |
365 | $display("s2_wb_we_o = 0x%0x", s2_wb_we_o); | |
366 | end | |
367 | ||
368 | $stop; | |
369 | end | |
370 | end | |
371 | ||
372 | ||
373 | always @ (posedge wb_clk_i) | |
374 | begin | |
375 | if(s1_wb_err_i & s1_wb_cyc_o) begin | |
376 | $display("(%0t) ERROR: WB cycle finished with error acknowledge ", $time); | |
377 | $display("s1_wb_dat_o = 0x%0x", s1_wb_dat_o); | |
378 | $display("s1_wb_adr_o = 0x%0x", s1_wb_adr_o); | |
379 | $display("s1_wb_sel_o = 0x%0x", s1_wb_sel_o); | |
380 | $display("s1_wb_we_o = 0x%0x", s1_wb_we_o); | |
381 | $stop; | |
382 | end | |
383 | if(s2_wb_err_i & s2_wb_cyc_o) begin | |
384 | $display("(%0t) ERROR: WB cycle finished with error acknowledge ", $time); | |
385 | $display("s2_wb_dat_o = 0x%0x", s2_wb_dat_o); | |
386 | $display("s2_wb_adr_o = 0x%0x", s2_wb_adr_o); | |
387 | $display("s2_wb_sel_o = 0x%0x", s2_wb_sel_o); | |
388 | $display("s2_wb_we_o = 0x%0x", s2_wb_we_o); | |
389 | $stop; | |
390 | end | |
391 | end | |
392 | ||
393 | ||
394 | ||
395 | endmodule |