1 |
189 |
mohor |
//////////////////////////////////////////////////////////////////////
|
2 |
|
|
//// ////
|
3 |
|
|
//// tb_ethernet_with_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: not supported by cvs2svn $
|
44 |
227 |
tadejm |
// Revision 1.2 2002/10/11 13:29:28 mohor
|
45 |
|
|
// Bist signals added.
|
46 |
|
|
//
|
47 |
216 |
mohor |
// Revision 1.1 2002/09/18 16:40:40 mohor
|
48 |
|
|
// Simple testbench that includes eth_cop, eth_host and eth_memory modules.
|
49 |
|
|
// This testbench is used for testing the whole environment. Use tb_ethernet
|
50 |
|
|
// testbench for testing just the ethernet MAC core (many tests).
|
51 |
189 |
mohor |
//
|
52 |
|
|
//
|
53 |
|
|
//
|
54 |
216 |
mohor |
//
|
55 |
189 |
mohor |
|
56 |
|
|
|
57 |
|
|
|
58 |
|
|
`include "tb_eth_defines.v"
|
59 |
|
|
`include "eth_defines.v"
|
60 |
|
|
`include "timescale.v"
|
61 |
|
|
|
62 |
|
|
module tb_ethernet_with_cop();
|
63 |
|
|
|
64 |
|
|
|
65 |
|
|
parameter Tp = 1;
|
66 |
|
|
|
67 |
|
|
|
68 |
|
|
reg wb_clk_o;
|
69 |
|
|
reg wb_rst_o;
|
70 |
|
|
|
71 |
|
|
reg mtx_clk;
|
72 |
|
|
reg mrx_clk;
|
73 |
|
|
|
74 |
|
|
wire [3:0] MTxD;
|
75 |
|
|
wire MTxEn;
|
76 |
|
|
wire MTxErr;
|
77 |
|
|
|
78 |
|
|
reg [3:0] MRxD; // This goes to PHY
|
79 |
|
|
reg MRxDV; // This goes to PHY
|
80 |
|
|
reg MRxErr; // This goes to PHY
|
81 |
|
|
reg MColl; // This goes to PHY
|
82 |
|
|
reg MCrs; // This goes to PHY
|
83 |
|
|
|
84 |
|
|
wire Mdi_I;
|
85 |
|
|
wire Mdo_O;
|
86 |
|
|
wire Mdo_OE;
|
87 |
|
|
wire Mdc_O;
|
88 |
|
|
|
89 |
|
|
integer tx_log;
|
90 |
|
|
integer rx_log;
|
91 |
|
|
|
92 |
|
|
reg StartTB;
|
93 |
|
|
|
94 |
|
|
`ifdef ETH_XILINX_RAMB4
|
95 |
|
|
reg gsr;
|
96 |
|
|
`endif
|
97 |
|
|
|
98 |
|
|
|
99 |
|
|
integer packet_ready_cnt, send_packet_cnt;
|
100 |
|
|
|
101 |
|
|
|
102 |
|
|
// Ethernet Slave Interface signals
|
103 |
|
|
wire [31:0] eth_sl_wb_adr_i, eth_sl_wb_dat_o, eth_sl_wb_dat_i;
|
104 |
|
|
wire [3:0] eth_sl_wb_sel_i;
|
105 |
|
|
wire eth_sl_wb_we_i, eth_sl_wb_cyc_i, eth_sl_wb_stb_i, eth_sl_wb_ack_o, eth_sl_wb_err_o;
|
106 |
|
|
|
107 |
|
|
// Memory Slave Interface signals
|
108 |
|
|
wire [31:0] mem_sl_wb_adr_i, mem_sl_wb_dat_o, mem_sl_wb_dat_i;
|
109 |
|
|
wire [3:0] mem_sl_wb_sel_i;
|
110 |
|
|
wire mem_sl_wb_we_i, mem_sl_wb_cyc_i, mem_sl_wb_stb_i, mem_sl_wb_ack_o, mem_sl_wb_err_o;
|
111 |
|
|
|
112 |
|
|
// Ethernet Master Interface signals
|
113 |
|
|
wire [31:0] eth_ma_wb_adr_o, eth_ma_wb_dat_i, eth_ma_wb_dat_o;
|
114 |
|
|
wire [3:0] eth_ma_wb_sel_o;
|
115 |
|
|
wire eth_ma_wb_we_o, eth_ma_wb_cyc_o, eth_ma_wb_stb_o, eth_ma_wb_ack_i, eth_ma_wb_err_i;
|
116 |
|
|
|
117 |
216 |
mohor |
`ifdef ETH_WISHBONE_B3
|
118 |
|
|
wire [2:0] eth_ma_wb_cti_o;
|
119 |
|
|
wire [1:0] eth_ma_wb_bte_o;
|
120 |
|
|
`endif
|
121 |
|
|
|
122 |
|
|
|
123 |
189 |
mohor |
// Host Master Interface signals
|
124 |
|
|
wire [31:0] host_ma_wb_adr_o, host_ma_wb_dat_i, host_ma_wb_dat_o;
|
125 |
|
|
wire [3:0] host_ma_wb_sel_o;
|
126 |
|
|
wire host_ma_wb_we_o, host_ma_wb_cyc_o, host_ma_wb_stb_o, host_ma_wb_ack_i, host_ma_wb_err_i;
|
127 |
|
|
|
128 |
|
|
|
129 |
|
|
|
130 |
|
|
eth_cop i_eth_cop
|
131 |
|
|
(
|
132 |
|
|
// WISHBONE common
|
133 |
|
|
.wb_clk_i(wb_clk_o), .wb_rst_i(wb_rst_o),
|
134 |
|
|
|
135 |
|
|
// WISHBONE MASTER 1 Ethernet Master Interface is connected here
|
136 |
|
|
.m1_wb_adr_i(eth_ma_wb_adr_o), .m1_wb_sel_i(eth_ma_wb_sel_o), .m1_wb_we_i (eth_ma_wb_we_o),
|
137 |
|
|
.m1_wb_dat_o(eth_ma_wb_dat_i), .m1_wb_dat_i(eth_ma_wb_dat_o), .m1_wb_cyc_i(eth_ma_wb_cyc_o),
|
138 |
|
|
.m1_wb_stb_i(eth_ma_wb_stb_o), .m1_wb_ack_o(eth_ma_wb_ack_i), .m1_wb_err_o(eth_ma_wb_err_i),
|
139 |
|
|
|
140 |
|
|
// WISHBONE MASTER 2 Host Interface is connected here
|
141 |
|
|
.m2_wb_adr_i(host_ma_wb_adr_o), .m2_wb_sel_i(host_ma_wb_sel_o), .m2_wb_we_i (host_ma_wb_we_o),
|
142 |
|
|
.m2_wb_dat_o(host_ma_wb_dat_i), .m2_wb_dat_i(host_ma_wb_dat_o), .m2_wb_cyc_i(host_ma_wb_cyc_o),
|
143 |
|
|
.m2_wb_stb_i(host_ma_wb_stb_o), .m2_wb_ack_o(host_ma_wb_ack_i), .m2_wb_err_o(host_ma_wb_err_i),
|
144 |
|
|
|
145 |
|
|
// WISHBONE slave 1 Ethernet Slave Interface is connected here
|
146 |
|
|
.s1_wb_adr_o(eth_sl_wb_adr_i), .s1_wb_sel_o(eth_sl_wb_sel_i), .s1_wb_we_o (eth_sl_wb_we_i),
|
147 |
|
|
.s1_wb_cyc_o(eth_sl_wb_cyc_i), .s1_wb_stb_o(eth_sl_wb_stb_i), .s1_wb_ack_i(eth_sl_wb_ack_o),
|
148 |
|
|
.s1_wb_err_i(eth_sl_wb_err_o), .s1_wb_dat_i(eth_sl_wb_dat_o), .s1_wb_dat_o(eth_sl_wb_dat_i),
|
149 |
|
|
|
150 |
|
|
// WISHBONE slave 2 Memory Interface is connected here
|
151 |
|
|
.s2_wb_adr_o(mem_sl_wb_adr_i), .s2_wb_sel_o(mem_sl_wb_sel_i), .s2_wb_we_o (mem_sl_wb_we_i),
|
152 |
|
|
.s2_wb_cyc_o(mem_sl_wb_cyc_i), .s2_wb_stb_o(mem_sl_wb_stb_i), .s2_wb_ack_i(mem_sl_wb_ack_o),
|
153 |
|
|
.s2_wb_err_i(mem_sl_wb_err_o), .s2_wb_dat_i(mem_sl_wb_dat_o), .s2_wb_dat_o(mem_sl_wb_dat_i)
|
154 |
|
|
);
|
155 |
|
|
|
156 |
|
|
|
157 |
|
|
|
158 |
|
|
|
159 |
|
|
// Connecting Ethernet top module
|
160 |
|
|
eth_top ethtop
|
161 |
|
|
(
|
162 |
|
|
// WISHBONE common
|
163 |
|
|
.wb_clk_i(wb_clk_o), .wb_rst_i(wb_rst_o),
|
164 |
|
|
|
165 |
|
|
// WISHBONE slave
|
166 |
|
|
.wb_adr_i(eth_sl_wb_adr_i[11:2]), .wb_sel_i(eth_sl_wb_sel_i), .wb_we_i(eth_sl_wb_we_i),
|
167 |
|
|
.wb_cyc_i(eth_sl_wb_cyc_i), .wb_stb_i(eth_sl_wb_stb_i), .wb_ack_o(eth_sl_wb_ack_o),
|
168 |
|
|
.wb_err_o(eth_sl_wb_err_o), .wb_dat_i(eth_sl_wb_dat_i), .wb_dat_o(eth_sl_wb_dat_o),
|
169 |
|
|
|
170 |
|
|
// WISHBONE master
|
171 |
|
|
.m_wb_adr_o(eth_ma_wb_adr_o), .m_wb_sel_o(eth_ma_wb_sel_o), .m_wb_we_o(eth_ma_wb_we_o),
|
172 |
|
|
.m_wb_dat_i(eth_ma_wb_dat_i), .m_wb_dat_o(eth_ma_wb_dat_o), .m_wb_cyc_o(eth_ma_wb_cyc_o),
|
173 |
|
|
.m_wb_stb_o(eth_ma_wb_stb_o), .m_wb_ack_i(eth_ma_wb_ack_i), .m_wb_err_i(eth_ma_wb_err_i),
|
174 |
|
|
|
175 |
216 |
mohor |
`ifdef ETH_WISHBONE_B3
|
176 |
|
|
.m_wb_cti_o(eth_ma_wb_cti_o), .m_wb_bte_o(eth_ma_wb_bte_o),
|
177 |
|
|
`endif
|
178 |
|
|
|
179 |
189 |
mohor |
//TX
|
180 |
|
|
.mtx_clk_pad_i(mtx_clk), .mtxd_pad_o(MTxD), .mtxen_pad_o(MTxEn), .mtxerr_pad_o(MTxErr),
|
181 |
|
|
|
182 |
|
|
//RX
|
183 |
|
|
.mrx_clk_pad_i(mrx_clk), .mrxd_pad_i(MRxD), .mrxdv_pad_i(MRxDV), .mrxerr_pad_i(MRxErr),
|
184 |
|
|
.mcoll_pad_i(MColl), .mcrs_pad_i(MCrs),
|
185 |
|
|
|
186 |
|
|
// MIIM
|
187 |
|
|
.mdc_pad_o(Mdc_O), .md_pad_i(Mdi_I), .md_pad_o(Mdo_O), .md_padoe_o(Mdo_OE),
|
188 |
|
|
|
189 |
|
|
.int_o()
|
190 |
216 |
mohor |
|
191 |
|
|
// Bist
|
192 |
|
|
`ifdef ETH_BIST
|
193 |
227 |
tadejm |
,
|
194 |
|
|
.scanb_rst (1'b0),
|
195 |
|
|
.scanb_clk (1'b0),
|
196 |
|
|
.scanb_si (1'b0),
|
197 |
|
|
.scanb_so (),
|
198 |
|
|
.scanb_en (1'b0)
|
199 |
216 |
mohor |
`endif
|
200 |
|
|
|
201 |
189 |
mohor |
);
|
202 |
|
|
|
203 |
|
|
|
204 |
|
|
|
205 |
|
|
// Connecting Memory Interface Module
|
206 |
|
|
eth_memory i_eth_memory
|
207 |
|
|
(
|
208 |
|
|
// WISHBONE common
|
209 |
|
|
.wb_clk_i(wb_clk_o), .wb_rst_i(wb_rst_o),
|
210 |
|
|
|
211 |
|
|
// WISHBONE slave: Memory Interface is connected here
|
212 |
|
|
.wb_adr_i(mem_sl_wb_adr_i), .wb_sel_i(mem_sl_wb_sel_i), .wb_we_i (mem_sl_wb_we_i),
|
213 |
|
|
.wb_cyc_i(mem_sl_wb_cyc_i), .wb_stb_i(mem_sl_wb_stb_i), .wb_ack_o(mem_sl_wb_ack_o),
|
214 |
|
|
.wb_err_o(mem_sl_wb_err_o), .wb_dat_o(mem_sl_wb_dat_o), .wb_dat_i(mem_sl_wb_dat_i)
|
215 |
|
|
);
|
216 |
|
|
|
217 |
|
|
|
218 |
|
|
// Connecting Host Interface
|
219 |
|
|
eth_host eth_host
|
220 |
|
|
(
|
221 |
|
|
// WISHBONE common
|
222 |
|
|
.wb_clk_i(wb_clk_o), .wb_rst_i(wb_rst_o),
|
223 |
|
|
|
224 |
|
|
// WISHBONE master
|
225 |
|
|
.wb_adr_o(host_ma_wb_adr_o), .wb_sel_o(host_ma_wb_sel_o), .wb_we_o (host_ma_wb_we_o),
|
226 |
|
|
.wb_dat_i(host_ma_wb_dat_i), .wb_dat_o(host_ma_wb_dat_o), .wb_cyc_o(host_ma_wb_cyc_o),
|
227 |
|
|
.wb_stb_o(host_ma_wb_stb_o), .wb_ack_i(host_ma_wb_ack_i), .wb_err_i(host_ma_wb_err_i)
|
228 |
|
|
);
|
229 |
|
|
|
230 |
|
|
|
231 |
|
|
|
232 |
|
|
|
233 |
|
|
|
234 |
|
|
// Reset pulse
|
235 |
|
|
initial
|
236 |
|
|
begin
|
237 |
|
|
MCrs=0; // This should come from PHY
|
238 |
|
|
MColl=0; // This should come from PHY
|
239 |
|
|
MRxD=0; // This should come from PHY
|
240 |
|
|
MRxDV=0; // This should come from PHY
|
241 |
|
|
MRxErr=0; // This should come from PHY
|
242 |
|
|
packet_ready_cnt = 0;
|
243 |
|
|
send_packet_cnt = 0;
|
244 |
|
|
tx_log = $fopen("ethernet_tx.log");
|
245 |
|
|
rx_log = $fopen("ethernet_rx.log");
|
246 |
|
|
wb_rst_o = 1'b1;
|
247 |
|
|
`ifdef ETH_XILINX_RAMB4
|
248 |
|
|
gsr = 1'b0;
|
249 |
|
|
#100 gsr = 1'b1;
|
250 |
|
|
#100 gsr = 1'b0;
|
251 |
|
|
`endif
|
252 |
|
|
#100 wb_rst_o = 1'b0;
|
253 |
|
|
#100 StartTB = 1'b1;
|
254 |
|
|
end
|
255 |
|
|
|
256 |
|
|
`ifdef ETH_XILINX_RAMB4
|
257 |
|
|
assign glbl.GSR = gsr;
|
258 |
|
|
`endif
|
259 |
|
|
|
260 |
|
|
|
261 |
|
|
|
262 |
|
|
// Generating wb_clk_o clock
|
263 |
|
|
initial
|
264 |
|
|
begin
|
265 |
|
|
wb_clk_o=0;
|
266 |
216 |
mohor |
// forever #20 wb_clk_o = ~wb_clk_o; // 2*20 ns -> 25 MHz
|
267 |
|
|
forever #12.5 wb_clk_o = ~wb_clk_o; // 2*12.5 ns -> 40 MHz
|
268 |
189 |
mohor |
end
|
269 |
|
|
|
270 |
|
|
// Generating mtx_clk clock
|
271 |
|
|
initial
|
272 |
|
|
begin
|
273 |
|
|
mtx_clk=0;
|
274 |
|
|
#3 forever #20 mtx_clk = ~mtx_clk; // 2*20 ns -> 25 MHz
|
275 |
|
|
end
|
276 |
|
|
|
277 |
|
|
// Generating mrx_clk clock
|
278 |
|
|
initial
|
279 |
|
|
begin
|
280 |
|
|
mrx_clk=0;
|
281 |
|
|
#16 forever #20 mrx_clk = ~mrx_clk; // 2*20 ns -> 25 MHz
|
282 |
|
|
end
|
283 |
|
|
|
284 |
|
|
reg [31:0] tmp;
|
285 |
|
|
initial
|
286 |
|
|
begin
|
287 |
|
|
wait(StartTB); // Start of testbench
|
288 |
|
|
|
289 |
|
|
|
290 |
|
|
eth_host.wb_write(`ETH_MODER, 4'hf, 32'h0); // Reset OFF
|
291 |
|
|
eth_host.wb_read(`ETH_MODER, 4'hf, tmp);
|
292 |
|
|
eth_host.wb_write(`ETH_MAC_ADDR1, 4'hf, 32'h0002); // Set ETH_MAC_ADDR1 register
|
293 |
|
|
eth_host.wb_write(`ETH_MAC_ADDR0, 4'hf, 32'h03040506); // Set ETH_MAC_ADDR0 register
|
294 |
|
|
|
295 |
|
|
initialize_txbd(3);
|
296 |
216 |
mohor |
initialize_rxbd(4);
|
297 |
189 |
mohor |
|
298 |
|
|
// eth_host.wb_write(`ETH_MODER, 4'hf, `ETH_MODER_RXEN | `ETH_MODER_TXEN | `ETH_MODER_PRO |
|
299 |
|
|
// `ETH_MODER_CRCEN | `ETH_MODER_PAD); // Set MODER register
|
300 |
|
|
// eth_host.wb_write(`ETH_MODER, 4'hf, `ETH_MODER_RXEN | `ETH_MODER_TXEN |
|
301 |
|
|
// `ETH_MODER_CRCEN | `ETH_MODER_PAD); // Set MODER register
|
302 |
216 |
mohor |
// eth_host.wb_write(`ETH_MODER, 4'hf, `ETH_MODER_RXEN | `ETH_MODER_TXEN | `ETH_MODER_BRO |
|
303 |
|
|
// `ETH_MODER_CRCEN | `ETH_MODER_PAD); // Set MODER register
|
304 |
189 |
mohor |
// eth_host.wb_write(`ETH_MODER, 4'hf, `ETH_MODER_RXEN | `ETH_MODER_TXEN | `ETH_MODER_PRO |
|
305 |
|
|
// `ETH_MODER_CRCEN | `ETH_MODER_PAD | `ETH_MODER_LOOPBCK); // Set MODER register
|
306 |
216 |
mohor |
eth_host.wb_write(`ETH_MODER, 4'hf, `ETH_MODER_RXEN | `ETH_MODER_TXEN | `ETH_MODER_PRO |
|
307 |
|
|
`ETH_MODER_CRCEN | `ETH_MODER_PAD | `ETH_MODER_LOOPBCK |
|
308 |
|
|
`ETH_MODER_FULLD); // Set MODER register
|
309 |
189 |
mohor |
eth_host.wb_read(`ETH_MODER, 4'hf, tmp);
|
310 |
|
|
|
311 |
216 |
mohor |
set_packet(16'h364, 8'h1);
|
312 |
|
|
set_packet(16'h234, 8'h11);
|
313 |
189 |
mohor |
send_packet;
|
314 |
216 |
mohor |
repeat (1000) @(posedge mrx_clk); // Waiting for TxEthMac to finish transmit
|
315 |
|
|
|
316 |
|
|
// repeat (10000) @(posedge wb_clk_o); // Waiting for TxEthMac to finish transmit
|
317 |
|
|
set_packet(16'h534, 8'h21);
|
318 |
|
|
// set_packet(16'h34, 8'h31);
|
319 |
|
|
|
320 |
189 |
mohor |
/*
|
321 |
|
|
eth_host.wb_write(`ETH_CTRLMODER, 4'hf, 32'h4); // Enable Tx Flow control
|
322 |
|
|
eth_host.wb_write(`ETH_CTRLMODER, 4'hf, 32'h5); // Enable Tx Flow control
|
323 |
|
|
eth_host.wb_write(`ETH_TX_CTRL, 4'hf, 32'h10013); // Send Control frame with PAUSE_TV=0x0013
|
324 |
|
|
*/
|
325 |
216 |
mohor |
|
326 |
189 |
mohor |
send_packet;
|
327 |
216 |
mohor |
repeat (1000) @(posedge mrx_clk); // Waiting for TxEthMac to finish transmit
|
328 |
|
|
send_packet;
|
329 |
|
|
repeat (1000) @(posedge mrx_clk); // Waiting for TxEthMac to finish transmit
|
330 |
189 |
mohor |
|
331 |
216 |
mohor |
/*
|
332 |
|
|
send_packet;
|
333 |
|
|
*/
|
334 |
189 |
mohor |
|
335 |
|
|
|
336 |
216 |
mohor |
repeat (10000) @(posedge wb_clk_o); // Waiting for TxEthMac to finish transmit
|
337 |
189 |
mohor |
|
338 |
216 |
mohor |
/*
|
339 |
|
|
GetDataOnMRxD(113, `UNICAST_XFR); // LengthRx bytes is comming on MRxD[3:0] signals
|
340 |
|
|
|
341 |
|
|
repeat (10000) @(posedge wb_clk_o); // Waiting for TxEthMac to finish transmit
|
342 |
|
|
|
343 |
189 |
mohor |
GetDataOnMRxD(500, `BROADCAST_XFR); // LengthRx bytes is comming on MRxD[3:0] signals
|
344 |
|
|
|
345 |
|
|
repeat (1000) @(posedge mrx_clk); // Waiting for TxEthMac to finish transmit
|
346 |
|
|
|
347 |
|
|
|
348 |
|
|
GetDataOnMRxD(1200, `BROADCAST_XFR); // LengthRx bytes is comming on MRxD[3:0] signals
|
349 |
|
|
|
350 |
|
|
|
351 |
|
|
GetDataOnMRxD(1000, `UNICAST_XFR); // LengthRx bytes is comming on MRxD[3:0] signals
|
352 |
|
|
|
353 |
|
|
repeat (10000) @(posedge wb_clk_o); // Waiting for TxEthMac to finish transmit
|
354 |
|
|
|
355 |
216 |
mohor |
*/
|
356 |
189 |
mohor |
// Reading and printing interrupts
|
357 |
|
|
eth_host.wb_read(`ETH_INT, 4'hf, tmp);
|
358 |
|
|
$display("Print irq = 0x%0x", tmp);
|
359 |
|
|
|
360 |
|
|
//Clearing all interrupts
|
361 |
|
|
eth_host.wb_write(`ETH_INT, 4'hf, 32'h60);
|
362 |
|
|
|
363 |
|
|
// Reading and printing interrupts
|
364 |
|
|
eth_host.wb_read(`ETH_INT, 4'hf, tmp);
|
365 |
|
|
$display("Print irq = 0x%0x", tmp);
|
366 |
|
|
|
367 |
|
|
$display("\n\n End of simulation");
|
368 |
|
|
$stop;
|
369 |
|
|
|
370 |
|
|
|
371 |
|
|
|
372 |
|
|
end
|
373 |
|
|
|
374 |
|
|
|
375 |
216 |
mohor |
`ifdef ETH_WISHBONE_B3
|
376 |
189 |
mohor |
|
377 |
216 |
mohor |
integer single_cnt_tx, burst_cnt_tx, burst_cnt;
|
378 |
|
|
integer single_cnt_rx, burst_cnt_rx;
|
379 |
|
|
|
380 |
|
|
initial
|
381 |
|
|
begin
|
382 |
|
|
single_cnt_tx=0; burst_cnt_tx=0; burst_cnt=0;
|
383 |
|
|
single_cnt_rx=0; burst_cnt_rx=0;
|
384 |
|
|
end
|
385 |
|
|
|
386 |
|
|
// Single and burst cycle watcher
|
387 |
|
|
always @ (posedge wb_clk_o)
|
388 |
|
|
begin
|
389 |
|
|
if(eth_ma_wb_ack_i) begin
|
390 |
|
|
if(eth_ma_wb_cyc_o & eth_ma_wb_we_o & eth_ma_wb_cti_o==3'b000) begin
|
391 |
|
|
if(burst_cnt!==0)
|
392 |
|
|
$display("(%0t)(%m) ERROR !!! burst_cnt should be 0 because this is a single access", $time);
|
393 |
|
|
else
|
394 |
|
|
single_cnt_rx=single_cnt_rx+1;
|
395 |
|
|
end
|
396 |
|
|
else if(eth_ma_wb_cyc_o & !eth_ma_wb_we_o & eth_ma_wb_cti_o==3'b000) begin
|
397 |
|
|
if(burst_cnt!==0)
|
398 |
|
|
$display("(%0t)(%m) ERROR !!! burst_cnt should be 0 because this is a single access", $time);
|
399 |
|
|
else
|
400 |
|
|
single_cnt_tx=single_cnt_tx+1;
|
401 |
|
|
end
|
402 |
|
|
else if(eth_ma_wb_cyc_o & eth_ma_wb_cti_o==3'b010) begin // burst in progress
|
403 |
|
|
burst_cnt=burst_cnt+1;
|
404 |
|
|
end
|
405 |
|
|
else if(eth_ma_wb_cyc_o & eth_ma_wb_we_o & eth_ma_wb_cti_o==3'b111 & burst_cnt==(`ETH_BURST_LENGTH-1)) begin
|
406 |
|
|
burst_cnt_rx=burst_cnt_rx+1;
|
407 |
|
|
burst_cnt=0;
|
408 |
|
|
end
|
409 |
|
|
else if(eth_ma_wb_cyc_o & !eth_ma_wb_we_o & eth_ma_wb_cti_o==3'b111 & burst_cnt==(`ETH_BURST_LENGTH-1)) begin
|
410 |
|
|
burst_cnt_tx=burst_cnt_tx+1;
|
411 |
|
|
burst_cnt=0;
|
412 |
|
|
end
|
413 |
|
|
else
|
414 |
|
|
$display("(%0t)(%m) ERROR !!! Unknown cycle type or sequence", $time);
|
415 |
|
|
end
|
416 |
|
|
end
|
417 |
|
|
`endif // ETH_WISHBONE_B3
|
418 |
|
|
|
419 |
|
|
|
420 |
|
|
|
421 |
189 |
mohor |
task initialize_txbd;
|
422 |
|
|
input [6:0] txbd_num;
|
423 |
|
|
|
424 |
|
|
integer i;
|
425 |
|
|
integer bd_status_addr, buf_addr, bd_ptr_addr;
|
426 |
|
|
|
427 |
|
|
for(i=0; i<txbd_num; i=i+1) begin
|
428 |
|
|
buf_addr = `TX_BUF_BASE + i * 32'h600;
|
429 |
|
|
bd_status_addr = `TX_BD_BASE + i * 8;
|
430 |
|
|
bd_ptr_addr = bd_status_addr + 4;
|
431 |
|
|
|
432 |
|
|
// Initializing BD - status
|
433 |
|
|
if(i==txbd_num-1)
|
434 |
|
|
eth_host.wb_write(bd_status_addr, 4'hf, 32'h00007800); // last BD: + WRAP
|
435 |
|
|
else
|
436 |
|
|
eth_host.wb_write(bd_status_addr, 4'hf, 32'h00005800); // IRQ + PAD + CRC
|
437 |
|
|
|
438 |
|
|
eth_host.wb_write(bd_ptr_addr, 4'hf, buf_addr); // Initializing BD - pointer
|
439 |
|
|
end
|
440 |
|
|
endtask // initialize_txbd
|
441 |
|
|
|
442 |
|
|
|
443 |
|
|
task initialize_rxbd;
|
444 |
|
|
input [6:0] rxbd_num;
|
445 |
|
|
|
446 |
|
|
integer i;
|
447 |
|
|
integer bd_status_addr, buf_addr, bd_ptr_addr;
|
448 |
|
|
|
449 |
|
|
for(i=0; i<rxbd_num; i=i+1) begin
|
450 |
|
|
buf_addr = `RX_BUF_BASE + i * 32'h600;
|
451 |
|
|
bd_status_addr = `RX_BD_BASE + i * 8;
|
452 |
|
|
bd_ptr_addr = bd_status_addr + 4;
|
453 |
|
|
|
454 |
|
|
// Initializing BD - status
|
455 |
|
|
if(i==rxbd_num-1)
|
456 |
|
|
eth_host.wb_write(bd_status_addr, 4'hf, 32'h0000e000); // last BD: + WRAP
|
457 |
|
|
else
|
458 |
|
|
eth_host.wb_write(bd_status_addr, 4'hf, 32'h0000c000); // IRQ + PAD + CRC
|
459 |
|
|
|
460 |
|
|
eth_host.wb_write(bd_ptr_addr, 4'hf, buf_addr); // Initializing BD - pointer
|
461 |
|
|
end
|
462 |
|
|
endtask // initialize_rxbd
|
463 |
|
|
|
464 |
|
|
|
465 |
|
|
task set_packet;
|
466 |
|
|
input [15:0] len;
|
467 |
|
|
input [7:0] start_data;
|
468 |
|
|
|
469 |
|
|
integer i, sd;
|
470 |
|
|
integer bd_status_addr, bd_ptr_addr, buffer, bd;
|
471 |
|
|
|
472 |
|
|
begin
|
473 |
|
|
sd = start_data;
|
474 |
|
|
bd_status_addr = `TX_BD_BASE + packet_ready_cnt * 8;
|
475 |
|
|
bd_ptr_addr = bd_status_addr + 4;
|
476 |
|
|
|
477 |
|
|
// Reading BD + buffer pointer
|
478 |
|
|
eth_host.wb_read(bd_status_addr, 4'hf, bd);
|
479 |
|
|
eth_host.wb_read(bd_ptr_addr, 4'hf, buffer);
|
480 |
|
|
|
481 |
|
|
while(bd & `ETH_TX_BD_READY) begin // Buffer is ready. Don't touch !!!
|
482 |
|
|
repeat(100) @(posedge wb_clk_o);
|
483 |
|
|
i=i+1;
|
484 |
|
|
eth_host.wb_read(bd_status_addr, 4'hf, bd);
|
485 |
|
|
if(i>1000) begin
|
486 |
|
|
$display("(%0t)(%m)Waiting for TxBD ready to clear timeout", $time);
|
487 |
|
|
$stop;
|
488 |
|
|
end
|
489 |
|
|
end
|
490 |
|
|
|
491 |
|
|
// First write might not be word allign.
|
492 |
|
|
if(buffer[1:0]==1) begin
|
493 |
|
|
eth_host.wb_write(buffer-1, 4'h7, {8'h0, sd[7:0], sd[7:0]+3'h1, sd[7:0]+3'h2});
|
494 |
|
|
sd=sd+3;
|
495 |
|
|
i=3;
|
496 |
|
|
end
|
497 |
|
|
else if(buffer[1:0]==2) begin
|
498 |
|
|
eth_host.wb_write(buffer-2, 4'h3, {16'h0, sd[7:0], sd[7:0]+3'h1});
|
499 |
|
|
sd=sd+2;
|
500 |
|
|
i=2;
|
501 |
|
|
end
|
502 |
|
|
else if(buffer[1:0]==3) begin
|
503 |
|
|
eth_host.wb_write(buffer-3, 4'h1, {24'h0, sd[7:0]});
|
504 |
|
|
sd=sd+1;
|
505 |
|
|
i=1;
|
506 |
|
|
end
|
507 |
|
|
else
|
508 |
|
|
i=0;
|
509 |
|
|
|
510 |
|
|
|
511 |
|
|
for(i=i; i<len-4; i=i+4) begin // Last 0-3 bytes are not written
|
512 |
|
|
eth_host.wb_write(buffer+i, 4'hf, {sd[7:0], sd[7:0]+3'h1, sd[7:0]+3'h2, sd[7:0]+3'h3});
|
513 |
|
|
sd=sd+4;
|
514 |
|
|
end
|
515 |
|
|
|
516 |
|
|
|
517 |
|
|
// Last word
|
518 |
|
|
if(len-i==3)
|
519 |
|
|
eth_host.wb_write(buffer+i, 4'he, {sd[7:0], sd[7:0]+3'h1, sd[7:0]+3'h2, 8'h0});
|
520 |
|
|
else if(len-i==2)
|
521 |
|
|
eth_host.wb_write(buffer+i, 4'hc, {sd[7:0], sd[7:0]+3'h1, 16'h0});
|
522 |
|
|
else if(len-i==1)
|
523 |
|
|
eth_host.wb_write(buffer+i, 4'h8, {sd[7:0], 24'h0});
|
524 |
|
|
else if(len-i==4)
|
525 |
|
|
eth_host.wb_write(buffer+i, 4'hf, {sd[7:0], sd[7:0]+3'h1, sd[7:0]+3'h2, sd[7:0]+3'h3});
|
526 |
|
|
else
|
527 |
|
|
$display("(%0t)(%m) ERROR", $time);
|
528 |
|
|
|
529 |
|
|
|
530 |
|
|
// Checking WRAP bit
|
531 |
|
|
if(bd & `ETH_TX_BD_WRAP)
|
532 |
|
|
packet_ready_cnt = 0;
|
533 |
|
|
else
|
534 |
|
|
packet_ready_cnt = packet_ready_cnt+1;
|
535 |
|
|
|
536 |
|
|
// Writing len to bd
|
537 |
|
|
bd = bd | (len<<16);
|
538 |
|
|
eth_host.wb_write(bd_status_addr, 4'hf, bd);
|
539 |
|
|
|
540 |
|
|
end
|
541 |
|
|
endtask // set_packet
|
542 |
|
|
|
543 |
|
|
|
544 |
|
|
task send_packet;
|
545 |
|
|
|
546 |
|
|
integer bd_status_addr, bd_ptr_addr, buffer, bd;
|
547 |
|
|
|
548 |
|
|
begin
|
549 |
|
|
bd_status_addr = `TX_BD_BASE + send_packet_cnt * 8;
|
550 |
|
|
bd_ptr_addr = bd_status_addr + 4;
|
551 |
|
|
|
552 |
|
|
// Reading BD + buffer pointer
|
553 |
|
|
eth_host.wb_read(bd_status_addr, 4'hf, bd);
|
554 |
|
|
eth_host.wb_read(bd_ptr_addr, 4'hf, buffer);
|
555 |
|
|
|
556 |
|
|
if(bd & `ETH_TX_BD_WRAP)
|
557 |
|
|
send_packet_cnt=0;
|
558 |
|
|
else
|
559 |
|
|
send_packet_cnt=send_packet_cnt+1;
|
560 |
|
|
|
561 |
|
|
// Setting ETH_TX_BD_READY bit
|
562 |
|
|
bd = bd | `ETH_TX_BD_READY;
|
563 |
|
|
eth_host.wb_write(bd_status_addr, 4'hf, bd);
|
564 |
|
|
end
|
565 |
|
|
|
566 |
|
|
|
567 |
|
|
endtask // send_packet
|
568 |
|
|
|
569 |
|
|
|
570 |
|
|
task GetDataOnMRxD;
|
571 |
|
|
input [15:0] Len;
|
572 |
|
|
input [31:0] TransferType;
|
573 |
|
|
integer tt;
|
574 |
|
|
|
575 |
|
|
begin
|
576 |
|
|
@ (posedge mrx_clk);
|
577 |
|
|
#1MRxDV=1'b1;
|
578 |
|
|
|
579 |
|
|
for(tt=0; tt<15; tt=tt+1)
|
580 |
|
|
begin
|
581 |
|
|
MRxD=4'h5; // preamble
|
582 |
|
|
@ (posedge mrx_clk);
|
583 |
|
|
#1;
|
584 |
|
|
end
|
585 |
|
|
|
586 |
|
|
MRxD=4'hd; // SFD
|
587 |
|
|
|
588 |
|
|
for(tt=1; tt<(Len+1); tt=tt+1)
|
589 |
|
|
begin
|
590 |
|
|
@ (posedge mrx_clk);
|
591 |
|
|
#1;
|
592 |
|
|
if(TransferType == `UNICAST_XFR && tt == 1)
|
593 |
|
|
MRxD= 4'h0; // Unicast transfer
|
594 |
|
|
else if(TransferType == `BROADCAST_XFR && tt < 7)
|
595 |
|
|
MRxD = 4'hf;
|
596 |
|
|
else
|
597 |
|
|
MRxD=tt[3:0]; // Multicast transfer
|
598 |
|
|
|
599 |
|
|
@ (posedge mrx_clk);
|
600 |
|
|
#1;
|
601 |
|
|
if(TransferType == `BROADCAST_XFR && tt < 7)
|
602 |
|
|
MRxD = 4'hf;
|
603 |
|
|
else
|
604 |
|
|
MRxD=tt[7:4];
|
605 |
|
|
end
|
606 |
|
|
|
607 |
|
|
@ (posedge mrx_clk);
|
608 |
|
|
#1;
|
609 |
|
|
MRxDV=1'b0;
|
610 |
|
|
end
|
611 |
|
|
endtask // GetDataOnMRxD
|
612 |
|
|
|
613 |
|
|
|
614 |
|
|
endmodule
|