1// 2// Copyright 2011 Ettus Research LLC 3// 4// This program is free software: you can redistribute it and/or modify 5// it under the terms of the GNU General Public License as published by 6// the Free Software Foundation, either version 3 of the License, or 7// (at your option) any later version. 8// 9// This program is distributed in the hope that it will be useful, 10// but WITHOUT ANY WARRANTY; without even the implied warranty of 11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12// GNU General Public License for more details. 13// 14// You should have received a copy of the GNU General Public License 15// along with this program. If not, see <http://www.gnu.org/licenses/>. 16// 17 18 19 20module simple_gemac_tb; 21`include "eth_tasks.v" 22 23 reg clk = 0; 24 reg reset = 1; 25 26 initial #1000 reset = 0; 27 always #50 clk = ~clk; 28 29 wire GMII_RX_DV, GMII_RX_ER, GMII_TX_EN, GMII_TX_ER, GMII_GTX_CLK; 30 wire [7:0] GMII_RXD, GMII_TXD; 31 32 wire rx_valid, rx_error, rx_ack; 33 wire tx_ack, tx_valid, tx_error; 34 35 wire [7:0] rx_data, tx_data; 36 37 reg [15:0] pause_time; 38 reg pause_req = 0; 39 40 wire GMII_RX_CLK = GMII_GTX_CLK; 41 42 reg [7:0] FORCE_DAT_ERR = 0; 43 reg FORCE_ERR = 0; 44 45 // Loopback 46 assign GMII_RX_DV = GMII_TX_EN; 47 assign GMII_RX_ER = GMII_TX_ER | FORCE_ERR; 48 assign GMII_RXD = GMII_TXD ^ FORCE_DAT_ERR; 49 50 wire [47:0] ucast_addr = 48'hF1F2_F3F4_F5F6; 51 wire [47:0] mcast_addr = 0; 52 wire pass_ucast =1, pass_mcast=0, pass_bcast=1, pass_pause=0, pass_all=0; 53 54 simple_gemac simple_gemac 55 (.clk125(clk), .reset(reset), 56 .GMII_GTX_CLK(GMII_GTX_CLK), .GMII_TX_EN(GMII_TX_EN), 57 .GMII_TX_ER(GMII_TX_ER), .GMII_TXD(GMII_TXD), 58 .GMII_RX_CLK(GMII_RX_CLK), .GMII_RX_DV(GMII_RX_DV), 59 .GMII_RX_ER(GMII_RX_ER), .GMII_RXD(GMII_RXD), 60 .pause_req(pause_req), .pause_time(pause_time), .pause_en(1), 61 .ucast_addr(ucast_addr), .mcast_addr(mcast_addr), 62 .pass_ucast(pass_ucast), .pass_mcast(pass_mcast), .pass_bcast(pass_bcast), 63 .pass_pause(pass_pause), .pass_all(pass_all), 64 .rx_clk(rx_clk), .rx_data(rx_data), 65 .rx_valid(rx_valid), .rx_error(rx_error), .rx_ack(rx_ack), 66 .tx_clk(tx_clk), .tx_data(tx_data), 67 .tx_valid(tx_valid), .tx_error(tx_error), .tx_ack(tx_ack) 68 ); 69 70 wire rx_ll_sof, rx_ll_eof, rx_ll_src_rdy, rx_ll_dst_rdy; 71 wire rx_ll_sof2, rx_ll_eof2, rx_ll_src_rdy2; 72 reg rx_ll_dst_rdy2 = 1; 73 wire [7:0] rx_ll_data, rx_ll_data2; 74 wire rx_ll_error, rx_ll_error2; 75 76 rxmac_to_ll8 rx_adapt 77 (.clk(clk), .reset(reset), .clear(0), 78 .rx_data(rx_data), .rx_valid(rx_valid), .rx_error(rx_error), .rx_ack(rx_ack), 79 .ll_data(rx_ll_data), .ll_sof(rx_ll_sof), .ll_eof(rx_ll_eof), .ll_error(rx_ll_error), 80 .ll_src_rdy(rx_ll_src_rdy), .ll_dst_rdy(rx_ll_dst_rdy)); 81 82 ll8_shortfifo rx_sfifo 83 (.clk(clk), .reset(reset), .clear(0), 84 .datain(rx_ll_data), .sof_i(rx_ll_sof), .eof_i(rx_ll_eof), 85 .error_i(rx_ll_error), .src_rdy_i(rx_ll_src_rdy), .dst_rdy_o(rx_ll_dst_rdy), 86 .dataout(rx_ll_data2), .sof_o(rx_ll_sof2), .eof_o(rx_ll_eof2), 87 .error_o(rx_ll_error2), .src_rdy_o(rx_ll_src_rdy2), .dst_rdy_i(rx_ll_dst_rdy2)); 88 89 wire tx_ll_sof, tx_ll_eof, tx_ll_src_rdy, tx_ll_dst_rdy; 90 reg tx_ll_sof2=0, tx_ll_eof2=0; 91 reg tx_ll_src_rdy2 = 0; 92 wire tx_ll_dst_rdy2; 93 wire [7:0] tx_ll_data; 94 reg [7:0] tx_ll_data2 = 0; 95 wire tx_ll_error; 96 wire tx_ll_error2 = 0; 97 98 ll8_shortfifo tx_sfifo 99 (.clk(clk), .reset(reset), .clear(clear), 100 .datain(tx_ll_data2), .sof_i(tx_ll_sof2), .eof_i(tx_ll_eof2), 101 .error_i(tx_ll_error2), .src_rdy_i(tx_ll_src_rdy2), .dst_rdy_o(tx_ll_dst_rdy2), 102 .dataout(tx_ll_data), .sof_o(tx_ll_sof), .eof_o(tx_ll_eof), 103 .error_o(tx_ll_error), .src_rdy_o(tx_ll_src_rdy), .dst_rdy_i(tx_ll_dst_rdy)); 104 105 ll8_to_txmac ll8_to_txmac 106 (.clk(clk), .reset(reset), .clear(clear), 107 .ll_data(tx_ll_data), .ll_sof(tx_ll_sof), .ll_eof(tx_ll_eof), 108 .ll_src_rdy(tx_ll_src_rdy), .ll_dst_rdy(tx_ll_dst_rdy), 109 .tx_data(tx_data), .tx_valid(tx_valid), .tx_error(tx_error), .tx_ack(tx_ack)); 110 111 initial $dumpfile("simple_gemac_tb.vcd"); 112 initial $dumpvars(0,simple_gemac_tb); 113 114 integer i; 115 reg [7:0] pkt_rom[0:65535]; 116 reg [1023:0] ROMFile; 117 118 initial 119 for (i=0;i<65536;i=i+1) 120 pkt_rom[i] <= 8'h0; 121 122 initial 123 begin 124 @(negedge reset); 125 repeat (10) 126 @(posedge clk); 127 SendFlowCtrl(16'h0007); // Send flow control 128 @(posedge clk); 129 #30000; 130 @(posedge clk); 131 SendFlowCtrl(16'h0009); // Increas flow control before it expires 132 #10000; 133 @(posedge clk); 134 SendFlowCtrl(16'h0000); // Cancel flow control before it expires 135 @(posedge clk); 136 137 SendPacket_to_ll8(8'hAA,10); // This packet gets dropped by the filters 138 repeat (10) 139 @(posedge clk); 140 141 SendPacketFromFile_ll8(60,0,0); // The rest are valid packets 142 repeat (10) 143 @(posedge clk); 144 145 SendPacketFromFile_ll8(61,0,0); 146 repeat (10) 147 @(posedge clk); 148 SendPacketFromFile_ll8(62,0,0); 149 repeat (10) 150 @(posedge clk); 151 SendPacketFromFile_ll8(63,0,0); 152 repeat (1) 153 @(posedge clk); 154 SendPacketFromFile_ll8(64,0,0); 155 repeat (10) 156 @(posedge clk); 157 SendPacketFromFile_ll8(59,0,0); 158 repeat (1) 159 @(posedge clk); 160 SendPacketFromFile_ll8(58,0,0); 161 repeat (1) 162 @(posedge clk); 163 SendPacketFromFile_ll8(100,0,0); 164 repeat (1) 165 @(posedge clk); 166 SendPacketFromFile_ll8(200,150,30); // waiting 14 empties the fifo, 15 underruns 167 repeat (1) 168 @(posedge clk); 169 SendPacketFromFile_ll8(100,0,30); 170 #10000 $finish; 171 end 172 173 // Force a CRC error 174 initial 175 begin 176 #90000; 177 @(posedge clk); 178 FORCE_DAT_ERR <= 8'h10; 179 @(posedge clk); 180 FORCE_DAT_ERR <= 8'h00; 181 end 182 183 // Force an RX_ER error (i.e. link loss) 184 initial 185 begin 186 #116000; 187 @(posedge clk); 188 FORCE_ERR <= 1; 189 @(posedge clk); 190 FORCE_ERR <= 0; 191 end 192 193 // Cause receive fifo to fill, causing an RX overrun 194 initial 195 begin 196 #126000; 197 @(posedge clk); 198 rx_ll_dst_rdy2 <= 0; 199 repeat (30) // Repeat of 14 fills the shortfifo, but works. 15 overflows 200 @(posedge clk); 201 rx_ll_dst_rdy2 <= 1; 202 end 203 204 // Tests: Send and recv flow control, send and receive good packets, RX CRC err, RX_ER, RX overrun, TX underrun 205 // Still need to test: CRC errors on Pause Frames 206 207 always @(posedge clk) 208 if(rx_ll_src_rdy2 & rx_ll_dst_rdy2) 209 begin 210 if(rx_ll_sof2 & ~rx_ll_eof2) 211 $display("RX-PKT-START %d",$time); 212 $display("RX-PKT SOF %d EOF %d ERR%d DAT %x",rx_ll_sof2,rx_ll_eof2,rx_ll_error2,rx_ll_data2); 213 if(rx_ll_eof2 & ~rx_ll_sof2) 214 $display("RX-PKT-END %d",$time); 215 end 216 217endmodule // simple_gemac_tb 218