URL
https://opencores.org/ocsvn/ethmac/ethmac/trunk
Subversion Repositories ethmac
Compare Revisions
- This comparison shows the changes necessary to convert path
/ethmac/tags/rel_20/bench
- from Rev 335 to Rev 338
- ↔ Reverse comparison
Rev 335 → Rev 338
/verilog/tb_eth_defines.v
0,0 → 1,212
////////////////////////////////////////////////////////////////////// |
//// //// |
//// tb_eth_defines.v //// |
//// //// |
//// This file is part of the Ethernet IP core project //// |
//// http://www.opencores.org/projects/ethmac/ //// |
//// //// |
//// Author(s): //// |
//// - Igor Mohor (igorM@opencores.org) //// |
//// //// |
//// All additional information is available in the Readme.txt //// |
//// file. //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001, 2002 Authors //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.10 2002/11/19 20:27:46 mohor |
// Temp version. |
// |
// Revision 1.9 2002/10/09 13:16:51 tadejm |
// Just back-up; not completed testbench and some testcases are not |
// wotking properly yet. |
// |
// Revision 1.8 2002/09/13 18:41:45 mohor |
// Rearanged testcases |
// |
// Revision 1.7 2002/09/13 12:29:14 mohor |
// Headers changed. |
// |
// Revision 1.6 2002/09/13 11:57:20 mohor |
// New testbench. Thanks to Tadej M - "The Spammer". |
// |
// Revision 1.3 2002/07/19 13:57:53 mohor |
// Testing environment also includes traffic cop, memory interface and host |
// interface. |
// |
// Revision 1.2 2002/05/03 10:22:17 mohor |
// TX_BUF_BASE changed. |
// |
// Revision 1.1 2002/03/19 12:53:54 mohor |
// Some defines that are used in testbench only were moved to tb_eth_defines.v |
// file. |
// |
// |
// |
// |
|
|
|
//`define VERBOSE // if log files of device modules are written |
|
`define MULTICAST_XFR 0 |
`define UNICAST_XFR 1 |
`define BROADCAST_XFR 2 |
`define UNICAST_WRONG_XFR 3 |
|
`define ETH_BASE 32'hd0000000 |
`define ETH_WIDTH 32'h800 |
`define MEMORY_BASE 32'h2000 |
`define MEMORY_WIDTH 32'h10000 |
`define TX_BUF_BASE `MEMORY_BASE |
`define RX_BUF_BASE `MEMORY_BASE + 32'h8000 |
`define TX_BD_BASE `ETH_BASE + 32'h00000400 |
`define RX_BD_BASE `ETH_BASE + 32'h00000600 |
|
/* Tx BD */ |
`define ETH_TX_BD_READY 32'h8000 /* Tx BD Ready */ |
`define ETH_TX_BD_IRQ 32'h4000 /* Tx BD IRQ Enable */ |
`define ETH_TX_BD_WRAP 32'h2000 /* Tx BD Wrap (last BD) */ |
`define ETH_TX_BD_PAD 32'h1000 /* Tx BD Pad Enable */ |
`define ETH_TX_BD_CRC 32'h0800 /* Tx BD CRC Enable */ |
|
`define ETH_TX_BD_UNDERRUN 32'h0100 /* Tx BD Underrun Status */ |
`define ETH_TX_BD_RETRY 32'h00F0 /* Tx BD Retry Status */ |
`define ETH_TX_BD_RETLIM 32'h0008 /* Tx BD Retransmission Limit Status */ |
`define ETH_TX_BD_LATECOL 32'h0004 /* Tx BD Late Collision Status */ |
`define ETH_TX_BD_DEFER 32'h0002 /* Tx BD Defer Status */ |
`define ETH_TX_BD_CARRIER 32'h0001 /* Tx BD Carrier Sense Lost Status */ |
|
/* Rx BD */ |
`define ETH_RX_BD_EMPTY 32'h8000 /* Rx BD Empty */ |
`define ETH_RX_BD_IRQ 32'h4000 /* Rx BD IRQ Enable */ |
`define ETH_RX_BD_WRAP 32'h2000 /* Rx BD Wrap (last BD) */ |
|
`define ETH_RX_BD_MISS 32'h0080 /* Rx BD Miss Status */ |
`define ETH_RX_BD_OVERRUN 32'h0040 /* Rx BD Overrun Status */ |
`define ETH_RX_BD_INVSIMB 32'h0020 /* Rx BD Invalid Symbol Status */ |
`define ETH_RX_BD_DRIBBLE 32'h0010 /* Rx BD Dribble Nibble Status */ |
`define ETH_RX_BD_TOOLONG 32'h0008 /* Rx BD Too Long Status */ |
`define ETH_RX_BD_SHORT 32'h0004 /* Rx BD Too Short Frame Status */ |
`define ETH_RX_BD_CRCERR 32'h0002 /* Rx BD CRC Error Status */ |
`define ETH_RX_BD_LATECOL 32'h0001 /* Rx BD Late Collision Status */ |
|
|
|
/* Register space */ |
`define ETH_MODER `ETH_BASE + 32'h00 /* Mode Register */ |
`define ETH_INT `ETH_BASE + 32'h04 /* Interrupt Source Register */ |
`define ETH_INT_MASK `ETH_BASE + 32'h08 /* Interrupt Mask Register */ |
`define ETH_IPGT `ETH_BASE + 32'h0C /* Back to Bak Inter Packet Gap Register */ |
`define ETH_IPGR1 `ETH_BASE + 32'h10 /* Non Back to Back Inter Packet Gap Register 1 */ |
`define ETH_IPGR2 `ETH_BASE + 32'h14 /* Non Back to Back Inter Packet Gap Register 2 */ |
`define ETH_PACKETLEN `ETH_BASE + 32'h18 /* Packet Length Register (min. and max.) */ |
`define ETH_COLLCONF `ETH_BASE + 32'h1C /* Collision and Retry Configuration Register */ |
`define ETH_TX_BD_NUM `ETH_BASE + 32'h20 /* Transmit Buffer Descriptor Number Register */ |
`define ETH_CTRLMODER `ETH_BASE + 32'h24 /* Control Module Mode Register */ |
`define ETH_MIIMODER `ETH_BASE + 32'h28 /* MII Mode Register */ |
`define ETH_MIICOMMAND `ETH_BASE + 32'h2C /* MII Command Register */ |
`define ETH_MIIADDRESS `ETH_BASE + 32'h30 /* MII Address Register */ |
`define ETH_MIITX_DATA `ETH_BASE + 32'h34 /* MII Transmit Data Register */ |
`define ETH_MIIRX_DATA `ETH_BASE + 32'h38 /* MII Receive Data Register */ |
`define ETH_MIISTATUS `ETH_BASE + 32'h3C /* MII Status Register */ |
`define ETH_MAC_ADDR0 `ETH_BASE + 32'h40 /* MAC Individual Address Register 0 */ |
`define ETH_MAC_ADDR1 `ETH_BASE + 32'h44 /* MAC Individual Address Register 1 */ |
`define ETH_HASH_ADDR0 `ETH_BASE + 32'h48 /* Hash Register 0 */ |
`define ETH_HASH_ADDR1 `ETH_BASE + 32'h4C /* Hash Register 1 */ |
`define ETH_TX_CTRL `ETH_BASE + 32'h50 /* Tx Control Register */ |
|
|
/* MODER Register */ |
`define ETH_MODER_RXEN 32'h00000001 /* Receive Enable */ |
`define ETH_MODER_TXEN 32'h00000002 /* Transmit Enable */ |
`define ETH_MODER_NOPRE 32'h00000004 /* No Preamble */ |
`define ETH_MODER_BRO 32'h00000008 /* Reject Broadcast */ |
`define ETH_MODER_IAM 32'h00000010 /* Use Individual Hash */ |
`define ETH_MODER_PRO 32'h00000020 /* Promiscuous (receive all) */ |
`define ETH_MODER_IFG 32'h00000040 /* Min. IFG not required */ |
`define ETH_MODER_LOOPBCK 32'h00000080 /* Loop Back */ |
`define ETH_MODER_NOBCKOF 32'h00000100 /* No Backoff */ |
`define ETH_MODER_EXDFREN 32'h00000200 /* Excess Defer */ |
`define ETH_MODER_FULLD 32'h00000400 /* Full Duplex */ |
`define ETH_MODER_RST 32'h00000800 /* Reset MAC */ |
`define ETH_MODER_DLYCRCEN 32'h00001000 /* Delayed CRC Enable */ |
`define ETH_MODER_CRCEN 32'h00002000 /* CRC Enable */ |
`define ETH_MODER_HUGEN 32'h00004000 /* Huge Enable */ |
`define ETH_MODER_PAD 32'h00008000 /* Pad Enable */ |
`define ETH_MODER_RECSMALL 32'h00010000 /* Receive Small */ |
|
/* Interrupt Source Register */ |
`define ETH_INT_TXB 32'h00000001 /* Transmit Buffer IRQ */ |
`define ETH_INT_TXE 32'h00000002 /* Transmit Error IRQ */ |
`define ETH_INT_RXB 32'h00000004 /* Receive Buffer IRQ */ |
`define ETH_INT_RXE 32'h00000008 /* Receive Error IRQ */ |
`define ETH_INT_BUSY 32'h00000010 /* Busy IRQ */ |
`define ETH_INT_TXC 32'h00000020 /* Transmit Control Frame IRQ */ |
`define ETH_INT_RXC 32'h00000040 /* Received Control Frame IRQ */ |
|
/* Interrupt Mask Register */ |
`define ETH_INT_MASK_TXB 32'h00000001 /* Transmit Buffer IRQ Mask */ |
`define ETH_INT_MASK_TXE 32'h00000002 /* Transmit Error IRQ Mask */ |
`define ETH_INT_MASK_RXF 32'h00000004 /* Receive Frame IRQ Mask */ |
`define ETH_INT_MASK_RXE 32'h00000008 /* Receive Error IRQ Mask */ |
`define ETH_INT_MASK_BUSY 32'h00000010 /* Busy IRQ Mask */ |
`define ETH_INT_MASK_TXC 32'h00000020 /* Transmit Control Frame IRQ Mask */ |
`define ETH_INT_MASK_RXC 32'h00000040 /* Received Control Frame IRQ Mask */ |
|
/* Control Module Mode Register */ |
`define ETH_CTRLMODER_PASSALL 32'h00000001 /* Pass Control Frames */ |
`define ETH_CTRLMODER_RXFLOW 32'h00000002 /* Receive Control Flow Enable */ |
`define ETH_CTRLMODER_TXFLOW 32'h00000004 /* Transmit Control Flow Enable */ |
|
/* MII Mode Register */ |
`define ETH_MIIMODER_CLKDIV 32'h000000FF /* Clock Divider */ |
`define ETH_MIIMODER_NOPRE 32'h00000100 /* No Preamble */ |
`define ETH_MIIMODER_RST 32'h00000200 /* MIIM Reset */ |
|
/* MII Command Register */ |
`define ETH_MIICOMMAND_SCANSTAT 32'h00000001 /* Scan Status */ |
`define ETH_MIICOMMAND_RSTAT 32'h00000002 /* Read Status */ |
`define ETH_MIICOMMAND_WCTRLDATA 32'h00000004 /* Write Control Data */ |
|
/* MII Address Register */ |
`define ETH_MIIADDRESS_FIAD 32'h0000001F /* PHY Address */ |
`define ETH_MIIADDRESS_RGAD 32'h00001F00 /* RGAD Address */ |
|
/* MII Status Register */ |
`define ETH_MIISTATUS_LINKFAIL 0 /* Link Fail bit */ |
`define ETH_MIISTATUS_BUSY 1 /* MII Busy bit */ |
`define ETH_MIISTATUS_NVALID 2 /* Data in MII Status Register is invalid bit */ |
|
/* TX Control Register */ |
`define ETH_TX_CTRL_TXPAUSERQ 32'h10000 /* Send PAUSE request */ |
|
|
`define TIME $display(" Time: %0t", $time) |
/verilog/tb_ethernet.v
0,0 → 1,19524
////////////////////////////////////////////////////////////////////// |
//// //// |
//// tb_ethernet.v //// |
//// //// |
//// This file is part of the Ethernet IP core project //// |
//// http://www.opencores.org/projects/ethmac/ //// |
//// //// |
//// Author(s): //// |
//// - Tadej Markovic, tadej@opencores.org //// |
//// - Igor Mohor, igorM@opencores.org //// |
//// //// |
//// All additional information is available in the Readme.txt //// |
//// file. //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001, 2002 Authors //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.27 2003/01/30 13:38:15 mohor |
// Underrun test fixed. Many other tests fixed. |
// |
// Revision 1.26 2003/01/22 19:40:10 tadejm |
// Backup version. Not fully working. |
// |
// Revision 1.25 2002/11/27 16:21:55 mohor |
// Full duplex control frames tested. |
// |
// Revision 1.24 2002/11/22 17:29:42 mohor |
// Flow control test almost finished. |
// |
// Revision 1.23 2002/11/22 02:12:16 mohor |
// test_mac_full_duplex_flow_control tests pretty much finished. |
// TEST 0: INSERT CONTROL FRM. WHILE TRANSMITTING NORMAL |
// FRM. AT 4 TX BD ( 10Mbps ) finished. |
// TEST 2: RECEIVE CONTROL FRAMES WITH PASSALL OPTION |
// TURNED OFF AT ONE RX BD ( 10Mbps ) finished. |
// |
// Revision 1.22 2002/11/21 13:56:50 mohor |
// test_mac_full_duplex_flow test 0 finished. Sending the control (PAUSE) frame |
// finished. |
// |
// Revision 1.21 2002/11/19 20:27:45 mohor |
// Temp version. |
// |
// Revision 1.20 2002/11/19 17:41:19 tadejm |
// Just some updates. |
// |
// Revision 1.19 2002/11/14 13:12:47 tadejm |
// Late collision is not reported any more. |
// |
// Revision 1.18 2002/10/18 17:03:34 tadejm |
// Changed BIST scan signals. |
// |
// Revision 1.17 2002/10/18 13:58:22 tadejm |
// Some code changed due to bug fixes. |
// |
// Revision 1.16 2002/10/09 13:16:51 tadejm |
// Just back-up; not completed testbench and some testcases are not |
// wotking properly yet. |
// |
// Revision 1.15 2002/09/20 14:29:12 tadej |
// Full duplex tests modified and testbench bug repaired. |
// |
// Revision 1.14 2002/09/18 17:56:38 tadej |
// Some additional reports added |
// |
// Revision 1.13 2002/09/16 17:53:49 tadej |
// Full duplex test improved. |
// |
// Revision 1.12 2002/09/16 15:10:42 mohor |
// MIIM test look better. |
// |
// Revision 1.11 2002/09/13 19:18:04 mohor |
// Bench outputs data to display every 128 bytes. |
// |
// Revision 1.10 2002/09/13 18:44:29 mohor |
// Beautiful tests merget together |
// |
// Revision 1.9 2002/09/13 18:41:45 mohor |
// Rearanged testcases |
// |
// Revision 1.8 2002/09/13 14:50:15 mohor |
// Bug in MIIM fixed. |
// |
// Revision 1.7 2002/09/13 12:29:14 mohor |
// Headers changed. |
// |
// Revision 1.6 2002/09/13 11:57:20 mohor |
// New testbench. Thanks to Tadej M - "The Spammer". |
// |
// Revision 1.2 2002/07/19 14:02:47 mohor |
// Clock mrx_clk set to 2.5 MHz. |
// |
// Revision 1.1 2002/07/19 13:57:53 mohor |
// Testing environment also includes traffic cop, memory interface and host |
// interface. |
// |
// |
// |
// |
// |
|
|
`include "eth_phy_defines.v" |
`include "wb_model_defines.v" |
`include "tb_eth_defines.v" |
`include "eth_defines.v" |
`include "timescale.v" |
|
module tb_ethernet(); |
|
|
reg wb_clk; |
reg wb_rst; |
wire wb_int; |
|
wire mtx_clk; // This goes to PHY |
wire mrx_clk; // This goes to PHY |
|
wire [3:0] MTxD; |
wire MTxEn; |
wire MTxErr; |
|
wire [3:0] MRxD; // This goes to PHY |
wire MRxDV; // This goes to PHY |
wire MRxErr; // This goes to PHY |
wire MColl; // This goes to PHY |
wire MCrs; // This goes to PHY |
|
wire Mdi_I; |
wire Mdo_O; |
wire Mdo_OE; |
tri Mdio_IO; |
wire Mdc_O; |
|
|
parameter Tp = 1; |
|
|
// Ethernet Slave Interface signals |
wire [31:0] eth_sl_wb_adr; |
wire [31:0] eth_sl_wb_adr_i, eth_sl_wb_dat_o, eth_sl_wb_dat_i; |
wire [3:0] eth_sl_wb_sel_i; |
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; |
|
// Ethernet Master Interface signals |
wire [31:0] eth_ma_wb_adr_o, eth_ma_wb_dat_i, eth_ma_wb_dat_o; |
wire [3:0] eth_ma_wb_sel_o; |
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; |
|
|
|
|
// Connecting Ethernet top module |
eth_top eth_top |
( |
// WISHBONE common |
.wb_clk_i(wb_clk), .wb_rst_i(wb_rst), |
|
// WISHBONE slave |
.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), |
.wb_cyc_i(eth_sl_wb_cyc_i), .wb_stb_i(eth_sl_wb_stb_i), .wb_ack_o(eth_sl_wb_ack_o), |
.wb_err_o(eth_sl_wb_err_o), .wb_dat_i(eth_sl_wb_dat_i), .wb_dat_o(eth_sl_wb_dat_o), |
|
// WISHBONE master |
.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), |
.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), |
.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), |
|
//TX |
.mtx_clk_pad_i(mtx_clk), .mtxd_pad_o(MTxD), .mtxen_pad_o(MTxEn), .mtxerr_pad_o(MTxErr), |
|
//RX |
.mrx_clk_pad_i(mrx_clk), .mrxd_pad_i(MRxD), .mrxdv_pad_i(MRxDV), .mrxerr_pad_i(MRxErr), |
.mcoll_pad_i(MColl), .mcrs_pad_i(MCrs), |
|
// MIIM |
.mdc_pad_o(Mdc_O), .md_pad_i(Mdi_I), .md_pad_o(Mdo_O), .md_padoe_o(Mdo_OE), |
|
.int_o(wb_int) |
|
// Bist |
`ifdef ETH_BIST |
, |
.scanb_rst (1'b0), |
.scanb_clk (1'b0), |
.scanb_si (1'b0), |
.scanb_so (), |
.scanb_en (1'b0) |
`endif |
); |
|
|
|
// Connecting Ethernet PHY Module |
assign Mdio_IO = Mdo_OE ? Mdo_O : 1'bz ; |
assign Mdi_I = Mdio_IO; |
integer phy_log_file_desc; |
|
eth_phy eth_phy |
( |
// WISHBONE reset |
.m_rst_n_i(!wb_rst), |
|
// MAC TX |
.mtx_clk_o(mtx_clk), .mtxd_i(MTxD), .mtxen_i(MTxEn), .mtxerr_i(MTxErr), |
|
// MAC RX |
.mrx_clk_o(mrx_clk), .mrxd_o(MRxD), .mrxdv_o(MRxDV), .mrxerr_o(MRxErr), |
.mcoll_o(MColl), .mcrs_o(MCrs), |
|
// MIIM |
.mdc_i(Mdc_O), .md_io(Mdio_IO), |
|
// SYSTEM |
.phy_log(phy_log_file_desc) |
); |
|
|
|
// Connecting WB Master as Host Interface |
integer host_log_file_desc; |
|
WB_MASTER_BEHAVIORAL wb_master |
( |
.CLK_I(wb_clk), |
.RST_I(wb_rst), |
.TAG_I({`WB_TAG_WIDTH{1'b0}}), |
.TAG_O(), |
.ACK_I(eth_sl_wb_ack_o), |
.ADR_O(eth_sl_wb_adr), // only eth_sl_wb_adr_i[11:2] used |
.CYC_O(eth_sl_wb_cyc_i), |
.DAT_I(eth_sl_wb_dat_o), |
.DAT_O(eth_sl_wb_dat_i), |
.ERR_I(eth_sl_wb_err_o), |
.RTY_I(1'b0), // inactive (1'b0) |
.SEL_O(eth_sl_wb_sel_i), |
.STB_O(eth_sl_wb_stb_i), |
.WE_O (eth_sl_wb_we_i), |
.CAB_O() // NOT USED for now! |
); |
|
assign eth_sl_wb_adr_i = {20'h0, eth_sl_wb_adr[11:2], 2'h0}; |
|
|
|
// Connecting WB Slave as Memory Interface Module |
integer memory_log_file_desc; |
|
WB_SLAVE_BEHAVIORAL wb_slave |
( |
.CLK_I(wb_clk), |
.RST_I(wb_rst), |
.ACK_O(eth_ma_wb_ack_i), |
.ADR_I(eth_ma_wb_adr_o), |
.CYC_I(eth_ma_wb_cyc_o), |
.DAT_O(eth_ma_wb_dat_i), |
.DAT_I(eth_ma_wb_dat_o), |
.ERR_O(eth_ma_wb_err_i), |
.RTY_O(), // NOT USED for now! |
.SEL_I(eth_ma_wb_sel_o), |
.STB_I(eth_ma_wb_stb_o), |
.WE_I (eth_ma_wb_we_o), |
.CAB_I(1'b0) // inactive (1'b0) |
); |
|
|
|
// Connecting WISHBONE Bus Monitors to ethernet master and slave interfaces |
integer wb_s_mon_log_file_desc ; |
integer wb_m_mon_log_file_desc ; |
|
WB_BUS_MON wb_eth_slave_bus_mon |
( |
// WISHBONE common |
.CLK_I(wb_clk), |
.RST_I(wb_rst), |
|
// WISHBONE slave |
.ACK_I(eth_sl_wb_ack_o), |
.ADDR_O({20'h0, eth_sl_wb_adr_i[11:2], 2'b0}), |
.CYC_O(eth_sl_wb_cyc_i), |
.DAT_I(eth_sl_wb_dat_o), |
.DAT_O(eth_sl_wb_dat_i), |
.ERR_I(eth_sl_wb_err_o), |
.RTY_I(1'b0), |
.SEL_O(eth_sl_wb_sel_i), |
.STB_O(eth_sl_wb_stb_i), |
.WE_O (eth_sl_wb_we_i), |
.TAG_I({`WB_TAG_WIDTH{1'b0}}), |
.TAG_O(), |
.CAB_O(1'b0), |
.log_file_desc (wb_s_mon_log_file_desc) |
); |
|
WB_BUS_MON wb_eth_master_bus_mon |
( |
// WISHBONE common |
.CLK_I(wb_clk), |
.RST_I(wb_rst), |
|
// WISHBONE master |
.ACK_I(eth_ma_wb_ack_i), |
.ADDR_O(eth_ma_wb_adr_o), |
.CYC_O(eth_ma_wb_cyc_o), |
.DAT_I(eth_ma_wb_dat_i), |
.DAT_O(eth_ma_wb_dat_o), |
.ERR_I(eth_ma_wb_err_i), |
.RTY_I(1'b0), |
.SEL_O(eth_ma_wb_sel_o), |
.STB_O(eth_ma_wb_stb_o), |
.WE_O (eth_ma_wb_we_o), |
.TAG_I({`WB_TAG_WIDTH{1'b0}}), |
.TAG_O(), |
.CAB_O(1'b0), |
.log_file_desc(wb_m_mon_log_file_desc) |
); |
|
|
|
reg StartTB; |
integer tb_log_file; |
|
initial |
begin |
tb_log_file = $fopen("../log/eth_tb.log"); |
if (tb_log_file < 2) |
begin |
$display("*E Could not open/create testbench log file in ../log/ directory!"); |
$finish; |
end |
$fdisplay(tb_log_file, "========================== ETHERNET IP Core Testbench results ==========================="); |
$fdisplay(tb_log_file, " "); |
|
phy_log_file_desc = $fopen("../log/eth_tb_phy.log"); |
if (phy_log_file_desc < 2) |
begin |
$fdisplay(tb_log_file, "*E Could not open/create eth_tb_phy.log file in ../log/ directory!"); |
$finish; |
end |
$fdisplay(phy_log_file_desc, "================ PHY Module Testbench access log ================"); |
$fdisplay(phy_log_file_desc, " "); |
|
memory_log_file_desc = $fopen("../log/eth_tb_memory.log"); |
if (memory_log_file_desc < 2) |
begin |
$fdisplay(tb_log_file, "*E Could not open/create eth_tb_memory.log file in ../log/ directory!"); |
$finish; |
end |
$fdisplay(memory_log_file_desc, "=============== MEMORY Module Testbench access log ==============="); |
$fdisplay(memory_log_file_desc, " "); |
|
host_log_file_desc = $fopen("../log/eth_tb_host.log"); |
if (host_log_file_desc < 2) |
begin |
$fdisplay(tb_log_file, "*E Could not open/create eth_tb_host.log file in ../log/ directory!"); |
$finish; |
end |
$fdisplay(host_log_file_desc, "================ HOST Module Testbench access log ================"); |
$fdisplay(host_log_file_desc, " "); |
|
wb_s_mon_log_file_desc = $fopen("../log/eth_tb_wb_s_mon.log"); |
if (wb_s_mon_log_file_desc < 2) |
begin |
$fdisplay(tb_log_file, "*E Could not open/create eth_tb_wb_s_mon.log file in ../log/ directory!"); |
$finish; |
end |
$fdisplay(wb_s_mon_log_file_desc, "============== WISHBONE Slave Bus Monitor error log =============="); |
$fdisplay(wb_s_mon_log_file_desc, " "); |
$fdisplay(wb_s_mon_log_file_desc, " Only ERRONEOUS conditions are logged !"); |
$fdisplay(wb_s_mon_log_file_desc, " "); |
|
wb_m_mon_log_file_desc = $fopen("../log/eth_tb_wb_m_mon.log"); |
if (wb_m_mon_log_file_desc < 2) |
begin |
$fdisplay(tb_log_file, "*E Could not open/create eth_tb_wb_m_mon.log file in ../log/ directory!"); |
$finish; |
end |
$fdisplay(wb_m_mon_log_file_desc, "============= WISHBONE Master Bus Monitor error log ============="); |
$fdisplay(wb_m_mon_log_file_desc, " "); |
$fdisplay(wb_m_mon_log_file_desc, " Only ERRONEOUS conditions are logged !"); |
$fdisplay(wb_m_mon_log_file_desc, " "); |
|
// Reset pulse |
wb_rst = 1'b1; |
#423 wb_rst = 1'b0; |
|
// Clear memories |
clear_memories; |
clear_buffer_descriptors; |
|
#423 StartTB = 1'b1; |
end |
|
|
|
// Generating wb_clk clock |
initial |
begin |
wb_clk=0; |
// forever #2.5 wb_clk = ~wb_clk; // 2*2.5 ns -> 200.0 MHz |
// forever #5 wb_clk = ~wb_clk; // 2*5 ns -> 100.0 MHz |
// forever #10 wb_clk = ~wb_clk; // 2*10 ns -> 50.0 MHz |
// forever #12.5 wb_clk = ~wb_clk; // 2*12.5 ns -> 40 MHz |
forever #15 wb_clk = ~wb_clk; // 2*10 ns -> 33.3 MHz |
// forever #20 wb_clk = ~wb_clk; // 2*20 ns -> 25 MHz |
// forever #25 wb_clk = ~wb_clk; // 2*25 ns -> 20.0 MHz |
// forever #31.25 wb_clk = ~wb_clk; // 2*31.25 ns -> 16.0 MHz |
// forever #50 wb_clk = ~wb_clk; // 2*50 ns -> 10.0 MHz |
// forever #55 wb_clk = ~wb_clk; // 2*55 ns -> 9.1 MHz |
end |
|
|
|
integer tests_successfull; |
integer tests_failed; |
reg [799:0] test_name; // used for tb_log_file |
|
reg [3:0] wbm_init_waits; // initial wait cycles between CYC_O and STB_O of WB Master |
reg [3:0] wbm_subseq_waits; // subsequent wait cycles between STB_Os of WB Master |
reg [2:0] wbs_waits; // wait cycles befor WB Slave responds |
reg [7:0] wbs_retries; // if RTY response, then this is the number of retries before ACK |
|
reg wbm_working; // tasks wbm_write and wbm_read set signal when working and reset it when stop working |
|
|
initial |
begin |
wait(StartTB); // Start of testbench |
|
// Initial global values |
tests_successfull = 0; |
tests_failed = 0; |
|
wbm_working = 0; |
|
wbm_init_waits = 4'h1; |
wbm_subseq_waits = 4'h3; |
wbs_waits = 4'h1; |
wbs_retries = 8'h2; |
wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries); |
|
// set DIFFERENT mrx_clk to mtx_clk! |
// eth_phy.set_mrx_equal_mtx = 1'b0; |
|
// Call tests |
// ---------- |
// test_access_to_mac_reg(0, 0); // 0 - 3 |
// test_mii(0, 17); // 0 - 17 |
test_note("PHY generates ideal Carrier sense and Collision signals for following tests"); |
eth_phy.carrier_sense_real_delay(0); |
test_mac_full_duplex_transmit(0, 21); // 0 - (21) |
test_mac_full_duplex_receive(0, 13); // 0 - 13 |
test_mac_full_duplex_flow_control(0, 4); // 0 - 4 |
// 4 is executed, everything is OK |
// test_mac_half_duplex_flow(0, 0); |
|
test_note("PHY generates 'real delayed' Carrier sense and Collision signals for following tests"); |
eth_phy.carrier_sense_real_delay(1); |
|
|
// Finish test's logs |
test_summary; |
$display("\n\n END of SIMULATION"); |
$fclose(tb_log_file | phy_log_file_desc | memory_log_file_desc | host_log_file_desc); |
$fclose(wb_s_mon_log_file_desc | wb_m_mon_log_file_desc); |
|
$stop; |
end |
|
|
|
////////////////////////////////////////////////////////////// |
// Test tasks |
////////////////////////////////////////////////////////////// |
|
task test_access_to_mac_reg; |
input [31:0] start_task; |
input [31:0] end_task; |
integer bit_start_1; |
integer bit_end_1; |
integer bit_start_2; |
integer bit_end_2; |
integer num_of_reg; |
integer i_addr; |
integer i_data; |
integer i_length; |
integer tmp_data; |
reg [31:0] tx_bd_num; |
reg [((`MAX_BLK_SIZE * 32) - 1):0] burst_data; |
reg [((`MAX_BLK_SIZE * 32) - 1):0] burst_tmp_data; |
integer i; |
integer i1; |
integer i2; |
integer i3; |
integer fail; |
integer test_num; |
reg [31:0] addr; |
reg [31:0] data; |
reg [31:0] data_max; |
begin |
// ACCESS TO MAC REGISTERS TEST |
test_heading("ACCESS TO MAC REGISTERS TEST"); |
$display(" "); |
$display("ACCESS TO MAC REGISTERS TEST"); |
fail = 0; |
|
// reset MAC registers |
hard_reset; |
// reset MAC and MII LOGIC with soft reset |
//reset_mac; |
//reset_mii; |
|
|
////////////////////////////////////////////////////////////////////// |
//// //// |
//// test_access_to_mac_reg: //// |
//// //// |
//// 0: Walking 1 with single cycles across MAC regs. //// |
//// 1: Walking 1 with single cycles across MAC buffer descript. //// |
//// 2: Test max reg. values and reg. values after writing //// |
//// inverse reset values and hard reset of the MAC //// |
//// 3: Test buffer desc. RAM preserving values after hard reset //// |
//// of the MAC and resetting the logic //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
for (test_num = start_task; test_num <= end_task; test_num = test_num + 1) |
begin |
|
//////////////////////////////////////////////////////////////////// |
//// //// |
//// Walking 1 with single cycles across MAC regs. //// |
//// //// |
//////////////////////////////////////////////////////////////////// |
if (test_num == 0) // Walking 1 with single cycles across MAC regs. |
begin |
// TEST 0: 'WALKING ONE' WITH SINGLE CYCLES ACROSS MAC REGISTERS ( VARIOUS BUS DELAYS ) |
test_name = "TEST 0: 'WALKING ONE' WITH SINGLE CYCLES ACROSS MAC REGISTERS ( VARIOUS BUS DELAYS )"; |
`TIME; $display(" TEST 0: 'WALKING ONE' WITH SINGLE CYCLES ACROSS MAC REGISTERS ( VARIOUS BUS DELAYS )"); |
|
data = 0; |
for (i = 0; i <= 4; i = i + 1) // for initial wait cycles on WB bus |
begin |
wbm_init_waits = i; |
wbm_subseq_waits = {$random} % 5; // it is not important for single accesses |
for (i_addr = 0; i_addr <= 32'h4C; i_addr = i_addr + 4) // register address |
begin |
addr = `ETH_BASE + i_addr; |
// set ranges of R/W bits |
case (addr) |
`ETH_MODER: |
begin |
bit_start_1 = 0; |
bit_end_1 = 16; |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
`ETH_INT: // READONLY - tested within INT test |
begin |
bit_start_1 = 32; // not used |
bit_end_1 = 32; // not used |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
`ETH_INT_MASK: |
begin |
bit_start_1 = 0; |
bit_end_1 = 6; |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
`ETH_IPGT: |
begin |
bit_start_1 = 0; |
bit_end_1 = 6; |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
`ETH_IPGR1: |
begin |
bit_start_1 = 0; |
bit_end_1 = 6; |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
`ETH_IPGR2: |
begin |
bit_start_1 = 0; |
bit_end_1 = 6; |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
`ETH_PACKETLEN: |
begin |
bit_start_1 = 0; |
bit_end_1 = 31; |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
`ETH_COLLCONF: |
begin |
bit_start_1 = 0; |
bit_end_1 = 5; |
bit_start_2 = 16; |
bit_end_2 = 19; |
end |
`ETH_TX_BD_NUM: |
begin |
bit_start_1 = 0; |
bit_end_1 = 7; |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
`ETH_CTRLMODER: |
begin |
bit_start_1 = 0; |
bit_end_1 = 2; |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
`ETH_MIIMODER: |
begin |
bit_start_1 = 0; |
bit_end_1 = 9; |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
`ETH_MIICOMMAND: // "WRITEONLY" - tested within MIIM test - 3 LSBits are not written here!!! |
begin |
bit_start_1 = 32; // not used |
bit_end_1 = 32; // not used |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
`ETH_MIIADDRESS: |
begin |
bit_start_1 = 0; |
bit_end_1 = 4; |
bit_start_2 = 8; |
bit_end_2 = 12; |
end |
`ETH_MIITX_DATA: |
begin |
bit_start_1 = 0; |
bit_end_1 = 15; |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
`ETH_MIIRX_DATA: // READONLY - tested within MIIM test |
begin |
bit_start_1 = 32; // not used |
bit_end_1 = 32; // not used |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
`ETH_MIISTATUS: // READONLY - tested within MIIM test |
begin |
bit_start_1 = 32; // not used |
bit_end_1 = 32; // not used |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
`ETH_MAC_ADDR0: |
begin |
bit_start_1 = 0; |
bit_end_1 = 31; |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
`ETH_MAC_ADDR1: |
begin |
bit_start_1 = 0; |
bit_end_1 = 15; |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
`ETH_HASH_ADDR0: |
begin |
bit_start_1 = 0; |
bit_end_1 = 31; |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
default: // `ETH_HASH_ADDR1: |
begin |
bit_start_1 = 0; |
bit_end_1 = 31; |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
endcase |
|
for (i_data = 0; i_data <= 31; i_data = i_data + 1) // the position of walking one |
begin |
data = 1'b1 << i_data; |
if ( (addr == `ETH_MIICOMMAND) && (i_data <= 2) ) // DO NOT WRITE to 3 LSBits of MIICOMMAND !!! |
; |
else |
begin |
wbm_write(addr, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
wait (wbm_working == 0); |
wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if ( ((i_data >= bit_start_1) && (i_data <= bit_end_1)) || |
((i_data >= bit_start_2) && (i_data <= bit_end_2)) ) // data should be equal to tmp_data |
begin |
if (tmp_data !== data) |
begin |
fail = fail + 1; |
test_fail("RW bit of the MAC register was not written or not read"); |
`TIME; |
$display("wbm_init_waits %d, addr %h, data %h, tmp_data %h", |
wbm_init_waits, addr, data, tmp_data); |
end |
end |
else // data should not be equal to tmp_data |
begin |
if (tmp_data === data) |
begin |
fail = fail + 1; |
test_fail("NON RW bit of the MAC register was written, but it shouldn't be"); |
`TIME; |
$display("wbm_init_waits %d, addr %h, data %h, tmp_data %h", |
wbm_init_waits, addr, data, tmp_data); |
end |
end |
end |
end |
end |
end |
// INTERMEDIATE DISPLAYS (The only one) |
$display(" ->buffer descriptors tested with 0, 1, 2, 3 and 4 bus delay cycles"); |
if(fail == 0) |
test_ok; |
else |
fail = 0; // Errors were reported previously |
end |
|
|
//////////////////////////////////////////////////////////////////// |
//// //// |
//// Walking 1 with single cycles across MAC buffer descript. //// |
//// //// |
//////////////////////////////////////////////////////////////////// |
if (test_num == 1) // Start Walking 1 with single cycles across MAC buffer descript. |
begin |
// TEST 1: 'WALKING ONE' WITH SINGLE CYCLES ACROSS MAC BUFFER DESC. ( VARIOUS BUS DELAYS ) |
test_name = "TEST 1: 'WALKING ONE' WITH SINGLE CYCLES ACROSS MAC BUFFER DESC. ( VARIOUS BUS DELAYS )"; |
`TIME; $display(" TEST 1: 'WALKING ONE' WITH SINGLE CYCLES ACROSS MAC BUFFER DESC. ( VARIOUS BUS DELAYS )"); |
|
data = 0; |
// set TX and RX buffer descriptors |
tx_bd_num = 32'h40; |
wbm_write(`ETH_TX_BD_NUM, tx_bd_num, 4'hF, 1, 0, 0); |
for (i = 0; i <= 4; i = i + 1) // for initial wait cycles on WB bus |
begin |
wbm_init_waits = i; |
wbm_subseq_waits = {$random} % 5; // it is not important for single accesses |
for (i_addr = 32'h400; i_addr <= 32'h7FC; i_addr = i_addr + 4) // buffer descriptor address |
begin |
addr = `ETH_BASE + i_addr; |
if (i_addr < (32'h400 + (tx_bd_num << 3))) // TX buffer descriptors |
begin |
// set ranges of R/W bits |
case (addr[3]) |
1'b0: // buffer control bits |
begin |
bit_start_1 = 0; |
bit_end_1 = 31; // 8; |
bit_start_2 = 11; |
bit_end_2 = 31; |
end |
default: // 1'b1: // buffer pointer |
begin |
bit_start_1 = 0; |
bit_end_1 = 31; |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
endcase |
end |
else // RX buffer descriptors |
begin |
// set ranges of R/W bits |
case (addr[3]) |
1'b0: // buffer control bits |
begin |
bit_start_1 = 0; |
bit_end_1 = 31; // 7; |
bit_start_2 = 13; |
bit_end_2 = 31; |
end |
default: // 1'b1: // buffer pointer |
begin |
bit_start_1 = 0; |
bit_end_1 = 31; |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
endcase |
end |
|
for (i_data = 0; i_data <= 31; i_data = i_data + 1) // the position of walking one |
begin |
data = 1'b1 << i_data; |
if ( (addr[3] == 0) && (i_data == 15) ) // DO NOT WRITE to this bit !!! |
; |
else |
begin |
wbm_write(addr, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if ( ((i_data >= bit_start_1) && (i_data <= bit_end_1)) || |
((i_data >= bit_start_2) && (i_data <= bit_end_2)) ) // data should be equal to tmp_data |
begin |
if (tmp_data !== data) |
begin |
fail = fail + 1; |
test_fail("RW bit of the MAC buffer descriptors was not written or not read"); |
`TIME; |
$display("wbm_init_waits %d, addr %h, data %h, tmp_data %h", |
wbm_init_waits, addr, data, tmp_data); |
end |
end |
else // data should not be equal to tmp_data |
begin |
if (tmp_data === data) |
begin |
fail = fail + 1; |
test_fail("NON RW bit of the MAC buffer descriptors was written, but it shouldn't be"); |
`TIME; |
$display("wbm_init_waits %d, addr %h, data %h, tmp_data %h", |
wbm_init_waits, addr, data, tmp_data); |
end |
end |
end |
end |
end |
// INTERMEDIATE DISPLAYS |
case (i) |
0: $display(" ->buffer descriptors tested with 0 bus delay"); |
1: $display(" ->buffer descriptors tested with 1 bus delay cycle"); |
2: $display(" ->buffer descriptors tested with 2 bus delay cycles"); |
3: $display(" ->buffer descriptors tested with 3 bus delay cycles"); |
default: $display(" ->buffer descriptors tested with 4 bus delay cycles"); |
endcase |
end |
if(fail == 0) |
test_ok; |
else |
fail = 0; |
end |
|
|
//////////////////////////////////////////////////////////////////// |
//// //// |
//// Test max reg. values and reg. values after writing //// |
//// inverse reset values and hard reset of the MAC //// |
//// //// |
//////////////////////////////////////////////////////////////////// |
if (test_num == 2) // Start this task |
begin |
// TEST 2: MAX REG. VALUES AND REG. VALUES AFTER WRITING INVERSE RESET VALUES AND HARD RESET OF THE MAC |
test_name = |
"TEST 2: MAX REG. VALUES AND REG. VALUES AFTER WRITING INVERSE RESET VALUES AND HARD RESET OF THE MAC"; |
`TIME; $display( |
" TEST 2: MAX REG. VALUES AND REG. VALUES AFTER WRITING INVERSE RESET VALUES AND HARD RESET OF THE MAC"); |
|
// reset MAC registers |
hard_reset; |
for (i = 0; i <= 4; i = i + 1) // 0, 2 - WRITE; 1, 3, 4 - READ |
begin |
for (i_addr = 0; i_addr <= 32'h4C; i_addr = i_addr + 4) // register address |
begin |
addr = `ETH_BASE + i_addr; |
// set ranges of R/W bits |
case (addr) |
`ETH_MODER: |
begin |
data = 32'h0000_A800; |
data_max = 32'h0001_FFFF; |
end |
`ETH_INT: // READONLY - tested within INT test |
begin |
data = 32'h0000_0000; |
data_max = 32'h0000_0000; |
end |
`ETH_INT_MASK: |
begin |
data = 32'h0000_0000; |
data_max = 32'h0000_007F; |
end |
`ETH_IPGT: |
begin |
data = 32'h0000_0012; |
data_max = 32'h0000_007F; |
end |
`ETH_IPGR1: |
begin |
data = 32'h0000_000C; |
data_max = 32'h0000_007F; |
end |
`ETH_IPGR2: |
begin |
data = 32'h0000_0012; |
data_max = 32'h0000_007F; |
end |
`ETH_PACKETLEN: |
begin |
data = 32'h0040_0600; |
data_max = 32'hFFFF_FFFF; |
end |
`ETH_COLLCONF: |
begin |
data = 32'h000F_003F; |
data_max = 32'h000F_003F; |
end |
`ETH_TX_BD_NUM: |
begin |
data = 32'h0000_0040; |
data_max = 32'h0000_0080; |
end |
`ETH_CTRLMODER: |
begin |
data = 32'h0000_0000; |
data_max = 32'h0000_0007; |
end |
`ETH_MIIMODER: |
begin |
data = 32'h0000_0064; |
data_max = 32'h0000_03FF; |
end |
`ETH_MIICOMMAND: // "WRITEONLY" - tested within MIIM test - 3 LSBits are not written here!!! |
begin |
data = 32'h0000_0000; |
data_max = 32'h0000_0007; |
end |
`ETH_MIIADDRESS: |
begin |
data = 32'h0000_0000; |
data_max = 32'h0000_1F1F; |
end |
`ETH_MIITX_DATA: |
begin |
data = 32'h0000_0000; |
data_max = 32'h0000_FFFF; |
end |
`ETH_MIIRX_DATA: // READONLY - tested within MIIM test |
begin |
data = 32'h0000_0000; |
data_max = 32'h0000_0000; |
end |
`ETH_MIISTATUS: // READONLY - tested within MIIM test |
begin |
data = 32'h0000_0000; |
data_max = 32'h0000_0000; |
end |
`ETH_MAC_ADDR0: |
begin |
data = 32'h0000_0000; |
data_max = 32'hFFFF_FFFF; |
end |
`ETH_MAC_ADDR1: |
begin |
data = 32'h0000_0000; |
data_max = 32'h0000_FFFF; |
end |
`ETH_HASH_ADDR0: |
begin |
data = 32'h0000_0000; |
data_max = 32'hFFFF_FFFF; |
end |
default: // `ETH_HASH_ADDR1: |
begin |
data = 32'h0000_0000; |
data_max = 32'hFFFF_FFFF; |
end |
endcase |
|
wbm_init_waits = {$random} % 3; |
wbm_subseq_waits = {$random} % 5; // it is not important for single accesses |
if (i == 0) |
begin |
wbm_write(addr, ~data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
end |
else if (i == 2) |
begin |
wbm_write(addr, 32'hFFFFFFFF, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
end |
else if ((i == 1) || (i == 4)) |
begin |
wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (tmp_data !== data) |
begin |
fail = fail + 1; |
test_fail("RESET value of the MAC register is not correct"); |
`TIME; |
$display(" addr %h, data %h, tmp_data %h", addr, data, tmp_data); |
end |
end |
else // check maximum values |
begin |
wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (addr == `ETH_TX_BD_NUM) // previous data should remain in this register |
begin |
if (tmp_data !== data) |
begin |
fail = fail + 1; |
test_fail("Previous value of the TX_BD_NUM register did not remain"); |
`TIME; |
$display(" addr %h, data_max %h, tmp_data %h", addr, data_max, tmp_data); |
end |
// try maximum (80) |
wbm_write(addr, data_max, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (tmp_data !== data_max) |
begin |
fail = fail + 1; |
test_fail("MAX value of the TX_BD_NUM register is not correct"); |
`TIME; |
$display(" addr %h, data_max %h, tmp_data %h", addr, data_max, tmp_data); |
end |
// try one less than maximum (80) |
wbm_write(addr, (data_max - 1), 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (tmp_data !== (data_max - 1)) |
begin |
fail = fail + 1; |
test_fail("ONE less than MAX value of the TX_BD_NUM register is not correct"); |
`TIME; |
$display(" addr %h, data_max %h, tmp_data %h", addr, data_max, tmp_data); |
end |
// try one more than maximum (80) |
wbm_write(addr, (data_max + 1), 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (tmp_data !== (data_max - 1)) // previous data should remain in this register |
begin |
fail = fail + 1; |
test_fail("Previous value of the TX_BD_NUM register did not remain"); |
`TIME; |
$display(" addr %h, data_max %h, tmp_data %h", addr, data_max, tmp_data); |
end |
end |
else |
begin |
if (tmp_data !== data_max) |
begin |
fail = fail + 1; |
test_fail("MAX value of the MAC register is not correct"); |
`TIME; |
$display(" addr %h, data_max %h, tmp_data %h", addr, data_max, tmp_data); |
end |
end |
end |
end |
// reset MAC registers |
if ((i == 0) || (i == 3)) |
hard_reset; |
end |
if(fail == 0) |
test_ok; |
else |
fail = 0; |
end |
|
|
//////////////////////////////////////////////////////////////////// |
//// //// |
//// Test buffer desc. ram preserving values after hard reset //// |
//// of the mac and reseting the logic //// |
//// //// |
//////////////////////////////////////////////////////////////////// |
if (test_num == 3) // Start this task |
begin |
// TEST 3: BUFFER DESC. RAM PRESERVING VALUES AFTER HARD RESET OF THE MAC AND RESETING THE LOGIC |
test_name = "TEST 3: BUFFER DESC. RAM PRESERVING VALUES AFTER HARD RESET OF THE MAC AND RESETING THE LOGIC"; |
`TIME; |
$display(" TEST 3: BUFFER DESC. RAM PRESERVING VALUES AFTER HARD RESET OF THE MAC AND RESETING THE LOGIC"); |
|
// reset MAC registers |
hard_reset; |
// reset LOGIC with soft reset |
// reset_mac; |
// reset_mii; |
for (i = 0; i <= 3; i = i + 1) // 0, 2 - WRITE; 1, 3 - READ |
begin |
for (i_addr = 32'h400; i_addr <= 32'h7FC; i_addr = i_addr + 4) // buffer descriptor address |
begin |
addr = `ETH_BASE + i_addr; |
|
wbm_init_waits = {$random} % 3; |
wbm_subseq_waits = {$random} % 5; // it is not important for single accesses |
if (i == 0) |
begin |
data = 32'hFFFFFFFF; |
wbm_write(addr, 32'hFFFFFFFF, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
end |
else if (i == 2) |
begin |
data = 32'h00000000; |
wbm_write(addr, 32'h00000000, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
end |
else |
begin |
wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (tmp_data !== data) |
begin |
fail = fail + 1; |
test_fail("PRESERVED value of the MAC buffer descriptors is not correct"); |
`TIME; |
$display(" addr %h, data %h, tmp_data %h", addr, data, tmp_data); |
end |
end |
end |
if ((i == 0) || (i == 2)) |
begin |
// reset MAC registers |
hard_reset; |
// reset LOGIC with soft reset |
// reset_mac; |
// reset_mii; |
end |
end |
if(fail == 0) |
test_ok; |
else |
fail = 0; |
end |
|
|
if (test_num == 4) // Start this task |
begin |
/* // TEST 4: 'WALKING ONE' WITH BURST CYCLES ACROSS MAC REGISTERS ( VARIOUS BUS DELAYS ) |
test_name = "TEST 4: 'WALKING ONE' WITH BURST CYCLES ACROSS MAC REGISTERS ( VARIOUS BUS DELAYS )"; |
`TIME; $display(" TEST 4: 'WALKING ONE' WITH BURST CYCLES ACROSS MAC REGISTERS ( VARIOUS BUS DELAYS )"); |
|
data = 0; |
burst_data = 0; |
burst_tmp_data = 0; |
i_length = 10; // two bursts for length 20 |
for (i = 0; i <= 4; i = i + 1) // for initial wait cycles on WB bus |
begin |
for (i1 = 0; i1 <= 4; i1 = i1 + 1) // for initial wait cycles on WB bus |
begin |
wbm_init_waits = i; |
wbm_subseq_waits = i1; |
#1; |
for (i_data = 0; i_data <= 31; i_data = i_data + 1) // the position of walking one |
begin |
data = 1'b1 << i_data; |
#1; |
for (i2 = 32'h4C; i2 >= 0; i2 = i2 - 4) |
begin |
burst_data = burst_data << 32; |
// DO NOT WRITE to 3 LSBits of MIICOMMAND !!! |
if ( ((`ETH_BASE + i2) == `ETH_MIICOMMAND) && (i_data <= 2) ) |
begin |
#1 burst_data[31:0] = 0; |
end |
else |
begin |
#1 burst_data[31:0] = data; |
end |
end |
#1; |
// 2 burst writes |
addr = `ETH_BASE; // address of a first burst |
wbm_write(addr, burst_data[(32 * 10 - 1):0], 4'hF, i_length, wbm_init_waits, wbm_subseq_waits); |
burst_tmp_data = burst_data >> (32 * i_length); |
addr = addr + 32'h28; // address of a second burst |
wbm_write(addr, burst_tmp_data[(32 * 10 - 1):0], 4'hF, i_length, wbm_init_waits, wbm_subseq_waits); |
#1; |
// 2 burst reads |
addr = `ETH_BASE; // address of a first burst |
wbm_read(addr, burst_tmp_data[(32 * 10 - 1):0], 4'hF, i_length, |
wbm_init_waits, wbm_subseq_waits); // first burst |
burst_tmp_data = burst_tmp_data << (32 * i_length); |
addr = addr + 32'h28; // address of a second burst |
wbm_read(addr, burst_tmp_data[(32 * 10 - 1):0], 4'hF, i_length, |
wbm_init_waits, wbm_subseq_waits); // second burst |
#1; |
for (i2 = 0; i2 <= 32'h4C; i2 = i2 + 4) |
begin |
// set ranges of R/W bits |
case (`ETH_BASE + i2) |
`ETH_MODER: |
begin |
bit_start_1 = 0; |
bit_end_1 = 16; |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
`ETH_INT: // READONLY - tested within INT test |
begin |
bit_start_1 = 32; // not used |
bit_end_1 = 32; // not used |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
`ETH_INT_MASK: |
begin |
bit_start_1 = 0; |
bit_end_1 = 6; |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
`ETH_IPGT: |
begin |
bit_start_1 = 0; |
bit_end_1 = 6; |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
`ETH_IPGR1: |
begin |
bit_start_1 = 0; |
bit_end_1 = 6; |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
`ETH_IPGR2: |
begin |
bit_start_1 = 0; |
bit_end_1 = 6; |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
`ETH_PACKETLEN: |
begin |
bit_start_1 = 0; |
bit_end_1 = 31; |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
`ETH_COLLCONF: |
begin |
bit_start_1 = 0; |
bit_end_1 = 5; |
bit_start_2 = 16; |
bit_end_2 = 19; |
end |
`ETH_TX_BD_NUM: |
begin |
bit_start_1 = 0; |
bit_end_1 = 7; |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
`ETH_CTRLMODER: |
begin |
bit_start_1 = 0; |
bit_end_1 = 2; |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
`ETH_MIIMODER: |
begin |
bit_start_1 = 0; |
bit_end_1 = 9; |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
`ETH_MIICOMMAND: // "WRITEONLY" - tested within MIIM test - 3 LSBits are not written here!!! |
begin |
bit_start_1 = 32; // not used |
bit_end_1 = 32; // not used |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
`ETH_MIIADDRESS: |
begin |
bit_start_1 = 0; |
bit_end_1 = 4; |
bit_start_2 = 8; |
bit_end_2 = 12; |
end |
`ETH_MIITX_DATA: |
begin |
bit_start_1 = 0; |
bit_end_1 = 15; |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
`ETH_MIIRX_DATA: // READONLY - tested within MIIM test |
begin |
bit_start_1 = 32; // not used |
bit_end_1 = 32; // not used |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
`ETH_MIISTATUS: // READONLY - tested within MIIM test |
begin |
bit_start_1 = 32; // not used |
bit_end_1 = 32; // not used |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
`ETH_MAC_ADDR0: |
begin |
bit_start_1 = 0; |
bit_end_1 = 31; |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
`ETH_MAC_ADDR1: |
begin |
bit_start_1 = 0; |
bit_end_1 = 15; |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
`ETH_HASH_ADDR0: |
begin |
bit_start_1 = 0; |
bit_end_1 = 31; |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
default: // `ETH_HASH_ADDR1: |
begin |
bit_start_1 = 0; |
bit_end_1 = 31; |
bit_start_2 = 32; // not used |
bit_end_2 = 32; // not used |
end |
endcase |
#1; |
// 3 LSBits of MIICOMMAND are NOT written !!! |
if ( ((`ETH_BASE + i2) == `ETH_MIICOMMAND) && (i_data <= 2) ) |
begin |
if (burst_tmp_data[31:0] !== burst_data[31:0]) |
begin |
fail = fail + 1; |
test_fail("NON WR bit of the MAC MIICOMMAND register was wrong written or read"); |
`TIME; |
$display("wbm_init_waits %d, wbm_subseq_waits %d, addr %h, data %h, tmp_data %h", |
wbm_init_waits, wbm_subseq_waits, i2, burst_data[31:0], burst_tmp_data[31:0]); |
end |
end |
else |
begin |
if ( ((i_data >= bit_start_1) && (i_data <= bit_end_1)) || |
((i_data >= bit_start_2) && (i_data <= bit_end_2)) ) // data should be equal to tmp_data |
begin |
if (burst_tmp_data[31:0] !== burst_data[31:0]) |
begin |
fail = fail + 1; |
test_fail("RW bit of the MAC register was not written or not read"); |
`TIME; |
$display("wbm_init_waits %d, wbm_subseq_waits %d, addr %h, data %h, tmp_data %h", |
wbm_init_waits, wbm_subseq_waits, i2, burst_data[31:0], burst_tmp_data[31:0]); |
end |
end |
else // data should not be equal to tmp_data |
begin |
if (burst_tmp_data[31:0] === burst_data[31:0]) |
begin |
fail = fail + 1; |
test_fail("NON RW bit of the MAC register was written, but it shouldn't be"); |
`TIME; |
$display("wbm_init_waits %d, wbm_subseq_waits %d, addr %h, data %h, tmp_data %h", |
wbm_init_waits, wbm_subseq_waits, i2, burst_data[31:0], burst_tmp_data[31:0]); |
end |
end |
end |
burst_tmp_data = burst_tmp_data >> 32; |
burst_data = burst_data >> 32; |
end |
end |
end |
end |
if(fail == 0) |
test_ok; |
else |
fail = 0;*/ |
end |
|
end |
|
end |
endtask // test_access_to_mac_reg |
|
|
task test_mii; |
input [31:0] start_task; |
input [31:0] end_task; |
integer i; |
integer i1; |
integer i2; |
integer i3; |
integer cnt; |
integer fail; |
integer test_num; |
reg [8:0] clk_div; // only 8 bits are valid! |
reg [4:0] phy_addr; |
reg [4:0] reg_addr; |
reg [15:0] phy_data; |
reg [15:0] tmp_data; |
begin |
// MIIM MODULE TEST |
test_heading("MIIM MODULE TEST"); |
$display(" "); |
$display("MIIM MODULE TEST"); |
fail = 0; |
|
// reset MAC registers |
hard_reset; |
// reset MAC and MII LOGIC with soft reset |
//reset_mac; |
//reset_mii; |
|
|
////////////////////////////////////////////////////////////////////// |
//// //// |
//// test_mii: //// |
//// //// |
//// 0: Test clock divider of mii management module with all //// |
//// possible frequences. //// |
//// 1: Test various readings from 'real' phy registers. //// |
//// 2: Test various writings to 'real' phy registers (control //// |
//// and non writable registers) //// |
//// 3: Test reset phy through mii management module //// |
//// 4: Test 'walking one' across phy address (with and without //// |
//// preamble) //// |
//// 5: Test 'walking one' across phy's register address (with //// |
//// and without preamble) //// |
//// 6: Test 'walking one' across phy's data (with and without //// |
//// preamble) //// |
//// 7: Test reading from phy with wrong phy address (host //// |
//// reading high 'z' data) //// |
//// 8: Test writing to phy with wrong phy address and reading //// |
//// from correct one //// |
//// 9: Test sliding stop scan command immediately after read //// |
//// request (with and without preamble) //// |
//// 10: Test sliding stop scan command immediately after write //// |
//// request (with and without preamble) //// |
//// 11: Test busy and nvalid status durations during write //// |
//// (with and without preamble) //// |
//// 12: Test busy and nvalid status durations during write //// |
//// (with and without preamble) //// |
//// 13: Test busy and nvalid status durations during scan (with //// |
//// and without preamble) //// |
//// 14: Test scan status from phy with detecting link-fail bit //// |
//// (with and without preamble) //// |
//// 15: Test scan status from phy with sliding link-fail bit //// |
//// (with and without preamble) //// |
//// 16: Test sliding stop scan command immediately after scan //// |
//// request (with and without preamble) //// |
//// 17: Test sliding stop scan command after 2. scan (with and //// |
//// without preamble) //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
for (test_num = start_task; test_num <= end_task; test_num = test_num + 1) |
begin |
|
//////////////////////////////////////////////////////////////////// |
//// //// |
//// Test clock divider of mii management module with all //// |
//// possible frequences. //// |
//// //// |
//////////////////////////////////////////////////////////////////// |
if (test_num == 0) // Test clock divider of mii management module with all possible frequences. |
begin |
// TEST 0: CLOCK DIVIDER OF MII MANAGEMENT MODULE WITH ALL POSSIBLE FREQUENCES |
test_name = "TEST 0: CLOCK DIVIDER OF MII MANAGEMENT MODULE WITH ALL POSSIBLE FREQUENCES"; |
`TIME; $display(" TEST 0: CLOCK DIVIDER OF MII MANAGEMENT MODULE WITH ALL POSSIBLE FREQUENCES"); |
|
wait(Mdc_O); // wait for MII clock to be 1 |
for(clk_div = 0; clk_div <= 255; clk_div = clk_div + 1) |
begin |
i1 = 0; |
i2 = 0; |
#Tp mii_set_clk_div(clk_div[7:0]); |
@(posedge Mdc_O); |
#Tp; |
fork |
begin |
@(posedge Mdc_O); |
#Tp; |
disable count_i1; |
disable count_i2; |
end |
begin: count_i1 |
forever |
begin |
@(posedge wb_clk); |
i1 = i1 + 1; |
#Tp; |
end |
end |
begin: count_i2 |
forever |
begin |
@(negedge wb_clk); |
i2 = i2 + 1; |
#Tp; |
end |
end |
join |
if((clk_div[7:0] == 0) || (clk_div[7:0] == 1) || (clk_div[7:0] == 2) || (clk_div[7:0] == 3)) |
begin |
if((i1 == i2) && (i1 == 2)) |
begin |
end |
else |
begin |
fail = fail + 1; |
test_fail("Clock divider of MII module did'nt divide frequency corectly (it should divide by 2)"); |
end |
end |
else |
begin |
if((i1 == i2) && (i1 == {clk_div[7:1], 1'b0})) |
begin |
end |
else |
begin |
fail = fail + 1; |
test_fail("Clock divider of MII module did'nt divide frequency corectly"); |
end |
end |
end |
if(fail == 0) |
test_ok; |
else |
fail = 0; |
end |
|
|
//////////////////////////////////////////////////////////////////// |
//// //// |
//// Test various readings from 'real' phy registers. //// |
//// //// |
//////////////////////////////////////////////////////////////////// |
if (test_num == 1) // Test various readings from 'real' phy registers. |
begin |
// TEST 1: VARIOUS READINGS FROM 'REAL' PHY REGISTERS |
test_name = "TEST 1: VARIOUS READINGS FROM 'REAL' PHY REGISTERS"; |
`TIME; $display(" TEST 1: VARIOUS READINGS FROM 'REAL' PHY REGISTERS"); |
|
// set the fastest possible MII |
clk_div = 0; |
mii_set_clk_div(clk_div[7:0]); |
// set address |
reg_addr = 5'h1F; |
phy_addr = 5'h1; |
while(reg_addr >= 5'h4) |
begin |
// read request |
#Tp mii_read_req(phy_addr, reg_addr); |
check_mii_busy; // wait for read to finish |
// read data |
wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (phy_data !== 16'hDEAD) |
begin |
test_fail("Wrong data was read from PHY from 'not used' address space"); |
fail = fail + 1; |
end |
if (reg_addr == 5'h4) // go out of for loop |
reg_addr = 5'h3; |
else |
reg_addr = reg_addr - 5'h9; |
end |
|
// set address |
reg_addr = 5'h3; |
// read request |
#Tp mii_read_req(phy_addr, reg_addr); |
check_mii_busy; // wait for read to finish |
// read data |
wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (phy_data !== {`PHY_ID2, `MAN_MODEL_NUM, `MAN_REVISION_NUM}) |
begin |
test_fail("Wrong data was read from PHY from ID register 2"); |
fail = fail + 1; |
end |
if(fail == 0) |
test_ok; |
else |
fail = 0; |
end |
|
|
//////////////////////////////////////////////////////////////////// |
//// //// |
//// Test various writings to 'real' phy registers (control //// |
//// and non writable registers) //// |
//// //// |
//////////////////////////////////////////////////////////////////// |
if (test_num == 2) // |
begin |
// TEST 2: VARIOUS WRITINGS TO 'REAL' PHY REGISTERS ( CONTROL AND NON WRITABLE REGISTERS ) |
test_name = "TEST 2: VARIOUS WRITINGS TO 'REAL' PHY REGISTERS ( CONTROL AND NON WRITABLE REGISTERS )"; |
`TIME; $display(" TEST 2: VARIOUS WRITINGS TO 'REAL' PHY REGISTERS ( CONTROL AND NON WRITABLE REGISTERS )"); |
|
// negate data and try to write into unwritable register |
tmp_data = ~phy_data; |
// write request |
#Tp mii_write_req(phy_addr, reg_addr, tmp_data); |
check_mii_busy; // wait for write to finish |
// read request |
#Tp mii_read_req(phy_addr, reg_addr); |
check_mii_busy; // wait for read to finish |
// read data |
wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (tmp_data !== phy_data) |
begin |
test_fail("Data was written into unwritable PHY register - ID register 2"); |
fail = fail + 1; |
end |
|
// set address |
reg_addr = 5'h0; // control register |
// read request |
#Tp mii_read_req(phy_addr, reg_addr); |
check_mii_busy; // wait for read to finish |
// read data |
wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// write request |
phy_data = 16'h7DFF; // bit 15 (RESET bit) and bit 9 are self clearing bits |
#Tp mii_write_req(phy_addr, reg_addr, phy_data); |
check_mii_busy; // wait for write to finish |
// read request |
#Tp mii_read_req(phy_addr, reg_addr); |
check_mii_busy; // wait for read to finish |
// read data |
wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (phy_data !== 16'h7DFF) |
begin |
test_fail("Data was not correctly written into OR read from writable PHY register - control register"); |
fail = fail + 1; |
end |
// write request |
#Tp mii_write_req(phy_addr, reg_addr, tmp_data); |
check_mii_busy; // wait for write to finish |
// read request |
#Tp mii_read_req(phy_addr, reg_addr); |
check_mii_busy; // wait for read to finish |
// read data |
wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (phy_data !== tmp_data) |
begin |
test_fail("Data was not correctly written into OR read from writable PHY register - control register"); |
fail = fail + 1; |
end |
if(fail == 0) |
test_ok; |
else |
fail = 0; |
end |
|
|
//////////////////////////////////////////////////////////////////// |
//// //// |
//// Test reset phy through mii management module //// |
//// //// |
//////////////////////////////////////////////////////////////////// |
if (test_num == 3) // |
begin |
// TEST 3: RESET PHY THROUGH MII MANAGEMENT MODULE |
test_name = "TEST 3: RESET PHY THROUGH MII MANAGEMENT MODULE"; |
`TIME; $display(" TEST 3: RESET PHY THROUGH MII MANAGEMENT MODULE"); |
|
// set address |
reg_addr = 5'h0; // control register |
// write request |
phy_data = 16'h7DFF; // bit 15 (RESET bit) and bit 9 are self clearing bits |
#Tp mii_write_req(phy_addr, reg_addr, phy_data); |
check_mii_busy; // wait for write to finish |
// read request |
#Tp mii_read_req(phy_addr, reg_addr); |
check_mii_busy; // wait for read to finish |
// read data |
wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (phy_data !== tmp_data) |
begin |
test_fail("Data was not correctly written into OR read from writable PHY register - control register"); |
fail = fail + 1; |
end |
// set reset bit - selfclearing bit in PHY |
phy_data = phy_data | 16'h8000; |
// write request |
#Tp mii_write_req(phy_addr, reg_addr, phy_data); |
check_mii_busy; // wait for write to finish |
// read request |
#Tp mii_read_req(phy_addr, reg_addr); |
check_mii_busy; // wait for read to finish |
// read data |
wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// check self clearing of reset bit |
if (tmp_data[15] !== 1'b0) |
begin |
test_fail("Reset bit should be self cleared - control register"); |
fail = fail + 1; |
end |
// check reset value of control register |
if (tmp_data !== {2'h0, (`LED_CFG1 || `LED_CFG2), `LED_CFG1, 3'h0, `LED_CFG3, 8'h0}) |
begin |
test_fail("PHY was not reset correctly AND/OR reset bit not self cleared"); |
fail = fail + 1; |
end |
if(fail == 0) |
test_ok; |
else |
fail = 0; |
end |
|
|
//////////////////////////////////////////////////////////////////// |
//// //// |
//// Test 'walking one' across phy address (with and without //// |
//// preamble) //// |
//// //// |
//////////////////////////////////////////////////////////////////// |
if (test_num == 4) // |
begin |
// TEST 4: 'WALKING ONE' ACROSS PHY ADDRESS ( WITH AND WITHOUT PREAMBLE ) |
test_name = "TEST 4: 'WALKING ONE' ACROSS PHY ADDRESS ( WITH AND WITHOUT PREAMBLE )"; |
`TIME; $display(" TEST 4: 'WALKING ONE' ACROSS PHY ADDRESS ( WITH AND WITHOUT PREAMBLE )"); |
|
// set PHY to test mode |
#Tp eth_phy.test_regs(1); // set test registers (wholy writable registers) and respond to all PHY addresses |
for (i = 0; i <= 1; i = i + 1) |
begin |
#Tp eth_phy.preamble_suppresed(i); |
#Tp eth_phy.clear_test_regs; |
// MII mode register |
wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i, 8'h0}), 4'hF, 1, wbm_init_waits, |
wbm_subseq_waits); |
// walk one across phy address |
for (phy_addr = 5'h1; phy_addr > 5'h0; phy_addr = phy_addr << 1) |
begin |
reg_addr = $random; |
tmp_data = $random; |
// write request |
#Tp mii_write_req(phy_addr, reg_addr, tmp_data); |
check_mii_busy; // wait for write to finish |
// read request |
#Tp mii_read_req(phy_addr, reg_addr); |
check_mii_busy; // wait for read to finish |
// read data |
wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
#Tp; |
if (phy_data !== tmp_data) |
begin |
if (i) |
test_fail("Data was not correctly written into OR read from test registers (without preamble)"); |
else |
test_fail("Data was not correctly written into OR read from test registers (with preamble)"); |
fail = fail + 1; |
end |
@(posedge wb_clk); |
#Tp; |
end |
end |
// set PHY to normal mode |
#Tp eth_phy.test_regs(0); |
#Tp eth_phy.preamble_suppresed(0); |
// MII mode register |
wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if(fail == 0) |
test_ok; |
else |
fail = 0; |
end |
|
|
//////////////////////////////////////////////////////////////////// |
//// //// |
//// Test 'walking one' across phy's register address (with //// |
//// and without preamble) //// |
//// //// |
//////////////////////////////////////////////////////////////////// |
if (test_num == 5) // |
begin |
// TEST 5: 'WALKING ONE' ACROSS PHY'S REGISTER ADDRESS ( WITH AND WITHOUT PREAMBLE ) |
test_name = "TEST 5: 'WALKING ONE' ACROSS PHY'S REGISTER ADDRESS ( WITH AND WITHOUT PREAMBLE )"; |
`TIME; $display(" TEST 5: 'WALKING ONE' ACROSS PHY'S REGISTER ADDRESS ( WITH AND WITHOUT PREAMBLE )"); |
|
// set PHY to test mode |
#Tp eth_phy.test_regs(1); // set test registers (wholy writable registers) and respond to all PHY addresses |
for (i = 0; i <= 1; i = i + 1) |
begin |
#Tp eth_phy.preamble_suppresed(i); |
#Tp eth_phy.clear_test_regs; |
// MII mode register |
wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i, 8'h0}), 4'hF, 1, wbm_init_waits, |
wbm_subseq_waits); |
// walk one across reg address |
for (reg_addr = 5'h1; reg_addr > 5'h0; reg_addr = reg_addr << 1) |
begin |
phy_addr = $random; |
tmp_data = $random; |
// write request |
#Tp mii_write_req(phy_addr, reg_addr, tmp_data); |
check_mii_busy; // wait for write to finish |
// read request |
#Tp mii_read_req(phy_addr, reg_addr); |
check_mii_busy; // wait for read to finish |
// read data |
wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
#Tp; |
if (phy_data !== tmp_data) |
begin |
if (i) |
test_fail("Data was not correctly written into OR read from test registers (without preamble)"); |
else |
test_fail("Data was not correctly written into OR read from test registers (with preamble)"); |
fail = fail + 1; |
end |
@(posedge wb_clk); |
#Tp; |
end |
end |
// set PHY to normal mode |
#Tp eth_phy.test_regs(0); |
#Tp eth_phy.preamble_suppresed(0); |
// MII mode register |
wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if(fail == 0) |
test_ok; |
else |
fail = 0; |
end |
|
|
//////////////////////////////////////////////////////////////////// |
//// //// |
//// Test 'walking one' across phy's data (with and without //// |
//// preamble) //// |
//// //// |
//////////////////////////////////////////////////////////////////// |
if (test_num == 6) // |
begin |
// TEST 6: 'WALKING ONE' ACROSS PHY'S DATA ( WITH AND WITHOUT PREAMBLE ) |
test_name = "TEST 6: 'WALKING ONE' ACROSS PHY'S DATA ( WITH AND WITHOUT PREAMBLE )"; |
`TIME; $display(" TEST 6: 'WALKING ONE' ACROSS PHY'S DATA ( WITH AND WITHOUT PREAMBLE )"); |
|
// set PHY to test mode |
#Tp eth_phy.test_regs(1); // set test registers (wholy writable registers) and respond to all PHY addresses |
for (i = 0; i <= 1; i = i + 1) |
begin |
#Tp eth_phy.preamble_suppresed(i); |
#Tp eth_phy.clear_test_regs; |
// MII mode register |
wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i, 8'h0}), 4'hF, 1, wbm_init_waits, |
wbm_subseq_waits); |
// walk one across data |
for (tmp_data = 16'h1; tmp_data > 16'h0; tmp_data = tmp_data << 1) |
begin |
phy_addr = $random; |
reg_addr = $random; |
// write request |
#Tp mii_write_req(phy_addr, reg_addr, tmp_data); |
check_mii_busy; // wait for write to finish |
// read request |
#Tp mii_read_req(phy_addr, reg_addr); |
check_mii_busy; // wait for read to finish |
// read data |
wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
#Tp; |
if (phy_data !== tmp_data) |
begin |
if (i) |
test_fail("Data was not correctly written into OR read from test registers (without preamble)"); |
else |
test_fail("Data was not correctly written into OR read from test registers (with preamble)"); |
fail = fail + 1; |
end |
@(posedge wb_clk); |
#Tp; |
end |
end |
// set PHY to normal mode |
#Tp eth_phy.test_regs(0); |
#Tp eth_phy.preamble_suppresed(0); |
// MII mode register |
wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if(fail == 0) |
test_ok; |
else |
fail = 0; |
end |
|
|
//////////////////////////////////////////////////////////////////// |
//// //// |
//// Test reading from phy with wrong phy address (host //// |
//// reading high 'z' data) //// |
//// //// |
//////////////////////////////////////////////////////////////////// |
if (test_num == 7) // |
begin |
// TEST 7: READING FROM PHY WITH WRONG PHY ADDRESS ( HOST READING HIGH 'Z' DATA ) |
test_name = "TEST 7: READING FROM PHY WITH WRONG PHY ADDRESS ( HOST READING HIGH 'Z' DATA )"; |
`TIME; $display(" TEST 7: READING FROM PHY WITH WRONG PHY ADDRESS ( HOST READING HIGH 'Z' DATA )"); |
|
phy_addr = 5'h2; // wrong PHY address |
// read request |
#Tp mii_read_req(phy_addr, reg_addr); |
check_mii_busy; // wait for read to finish |
// read data |
$display(" => Two errors will be displayed from WB Bus Monitor, because correct HIGH Z data was read"); |
wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (tmp_data !== 16'hzzzz) |
begin |
test_fail("Data was read from PHY register with wrong PHY address - control register"); |
fail = fail + 1; |
end |
if(fail == 0) |
test_ok; |
else |
fail = 0; |
end |
|
|
//////////////////////////////////////////////////////////////////// |
//// //// |
//// Test writing to phy with wrong phy address and reading //// |
//// from correct one //// |
//// //// |
//////////////////////////////////////////////////////////////////// |
if (test_num == 8) // |
begin |
// TEST 8: WRITING TO PHY WITH WRONG PHY ADDRESS AND READING FROM CORRECT ONE |
test_name = "TEST 8: WRITING TO PHY WITH WRONG PHY ADDRESS AND READING FROM CORRECT ONE"; |
`TIME; $display(" TEST 8: WRITING TO PHY WITH WRONG PHY ADDRESS AND READING FROM CORRECT ONE"); |
|
// set address |
reg_addr = 5'h0; // control register |
phy_addr = 5'h2; // wrong PHY address |
// write request |
phy_data = 16'h7DFF; // bit 15 (RESET bit) and bit 9 are self clearing bits |
#Tp mii_write_req(phy_addr, reg_addr, phy_data); |
check_mii_busy; // wait for write to finish |
|
phy_addr = 5'h1; // correct PHY address |
// read request |
#Tp mii_read_req(phy_addr, reg_addr); |
check_mii_busy; // wait for read to finish |
// read data |
wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (phy_data === tmp_data) |
begin |
test_fail("Data was written into PHY register with wrong PHY address - control register"); |
fail = fail + 1; |
end |
if(fail == 0) |
test_ok; |
else |
fail = 0; |
end |
|
|
//////////////////////////////////////////////////////////////////// |
//// //// |
//// Test sliding stop scan command immediately after read //// |
//// request (with and without preamble) //// |
//// //// |
//////////////////////////////////////////////////////////////////// |
if (test_num == 9) // |
begin |
// TEST 9: SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER READ REQUEST ( WITH AND WITHOUT PREAMBLE ) |
test_name = "TEST 9: SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER READ REQUEST ( WITH AND WITHOUT PREAMBLE )"; |
`TIME; |
$display(" TEST 9: SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER READ REQUEST ( WITH AND WITHOUT PREAMBLE )"); |
|
for (i2 = 0; i2 <= 1; i2 = i2 + 1) // choose preamble or not |
begin |
#Tp eth_phy.preamble_suppresed(i2); |
// MII mode register |
wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i2, 8'h0}), 4'hF, 1, wbm_init_waits, |
wbm_subseq_waits); |
i = 0; |
cnt = 0; |
while (i < 80) // delay for sliding of writing a STOP SCAN command |
begin |
for (i3 = 0; i3 <= 1; i3 = i3 + 1) // choose read or write after read will be finished |
begin |
// set address |
reg_addr = 5'h0; // control register |
phy_addr = 5'h1; // correct PHY address |
cnt = 0; |
// read request |
#Tp mii_read_req(phy_addr, reg_addr); |
fork |
begin |
repeat(i) @(posedge Mdc_O); |
// write command 0x0 into MII command register |
// MII command written while read in progress |
wbm_write(`ETH_MIICOMMAND, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
@(posedge wb_clk); |
#Tp check_mii_busy; // wait for read to finish |
end |
begin |
// wait for serial bus to become active |
wait(Mdio_IO !== 1'bz); |
// count transfer length |
while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) ) |
begin |
@(posedge Mdc_O); |
#Tp cnt = cnt + 1; |
end |
end |
join |
// check transfer length |
if (i2) // without preamble |
begin |
if (cnt != 33) // at this value Mdio_IO is HIGH Z |
begin |
test_fail("Read request did not proceed correctly, while SCAN STOP command was written"); |
fail = fail + 1; |
end |
end |
else // with preamble |
begin |
if (cnt != 65) // at this value Mdio_IO is HIGH Z |
begin |
test_fail("Read request did not proceed correctly, while SCAN STOP command was written"); |
fail = fail + 1; |
end |
end |
// check the BUSY signal to see if the bus is still IDLE |
for (i1 = 0; i1 < 8; i1 = i1 + 1) |
check_mii_busy; // wait for bus to become idle |
|
// try normal write or read after read was finished |
#Tp phy_data = {8'h7D, (i[7:0] + 1)}; |
#Tp cnt = 0; |
if (i3 == 0) // write after read |
begin |
// write request |
#Tp mii_write_req(phy_addr, reg_addr, phy_data); |
// wait for serial bus to become active |
wait(Mdio_IO !== 1'bz); |
// count transfer length |
while(Mdio_IO !== 1'bz) |
begin |
@(posedge Mdc_O); |
#Tp cnt = cnt + 1; |
end |
@(posedge Mdc_O); |
// read request |
#Tp mii_read_req(phy_addr, reg_addr); |
check_mii_busy; // wait for read to finish |
// read and check data |
wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (phy_data !== tmp_data) |
begin |
test_fail("Data was not correctly written into OR read from PHY register - control register"); |
fail = fail + 1; |
end |
end |
else // read after read |
begin |
// read request |
#Tp mii_read_req(phy_addr, reg_addr); |
// wait for serial bus to become active |
wait(Mdio_IO !== 1'bz); |
// count transfer length |
while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) ) |
begin |
@(posedge Mdc_O); |
#Tp cnt = cnt + 1; |
end |
@(posedge Mdc_O); |
check_mii_busy; // wait for read to finish |
// read and check data |
wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (phy_data !== tmp_data) |
begin |
test_fail("Data was not correctly written into OR read from PHY register - control register"); |
fail = fail + 1; |
end |
end |
// check if transfer was a proper length |
if (i2) // without preamble |
begin |
if (cnt != 33) // at this value Mdio_IO is HIGH Z |
begin |
test_fail("New request did not proceed correctly, after read request"); |
fail = fail + 1; |
end |
end |
else // with preamble |
begin |
if (cnt != 65) // at this value Mdio_IO is HIGH Z |
begin |
test_fail("New request did not proceed correctly, after read request"); |
fail = fail + 1; |
end |
end |
end |
#Tp; |
// set delay of writing the command |
if (i2) // without preamble |
begin |
case(i) |
0, 1: i = i + 1; |
18, 19, 20, 21, 22, |
23, 24, 25, 26, 27, |
28, 29, 30, 31, 32, |
33, 34, 35: i = i + 1; |
36: i = 80; |
default: i = 18; |
endcase |
end |
else // with preamble |
begin |
case(i) |
0, 1: i = i + 1; |
50, 51, 52, 53, 54, |
55, 56, 57, 58, 59, |
60, 61, 62, 63, 64, |
65, 66, 67: i = i + 1; |
68: i = 80; |
default: i = 50; |
endcase |
end |
@(posedge wb_clk); |
end |
end |
// set PHY to normal mode |
#Tp eth_phy.preamble_suppresed(0); |
// MII mode register |
wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if(fail == 0) |
test_ok; |
else |
fail = 0; |
end |
|
|
//////////////////////////////////////////////////////////////////// |
//// //// |
//// Test sliding stop scan command immediately after write //// |
//// request (with and without preamble) //// |
//// //// |
//////////////////////////////////////////////////////////////////// |
if (test_num == 10) // |
begin |
// TEST 10: SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER WRITE REQUEST ( WITH AND WITHOUT PREAMBLE ) |
test_name = "TEST 10: SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER WRITE REQUEST ( WITH AND WITHOUT PREAMBLE )"; |
`TIME; |
$display(" TEST 10: SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER WRITE REQUEST ( WITH AND WITHOUT PREAMBLE )"); |
|
for (i2 = 0; i2 <= 1; i2 = i2 + 1) // choose preamble or not |
begin |
#Tp eth_phy.preamble_suppresed(i2); |
// MII mode register |
wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i2, 8'h0}), 4'hF, 1, wbm_init_waits, |
wbm_subseq_waits); |
i = 0; |
cnt = 0; |
while (i < 80) // delay for sliding of writing a STOP SCAN command |
begin |
for (i3 = 0; i3 <= 1; i3 = i3 + 1) // choose read or write after write will be finished |
begin |
// set address |
reg_addr = 5'h0; // control register |
phy_addr = 5'h1; // correct PHY address |
cnt = 0; |
// write request |
phy_data = {8'h75, (i[7:0] + 1)}; |
#Tp mii_write_req(phy_addr, reg_addr, phy_data); |
fork |
begin |
repeat(i) @(posedge Mdc_O); |
// write command 0x0 into MII command register |
// MII command written while read in progress |
wbm_write(`ETH_MIICOMMAND, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
@(posedge wb_clk); |
#Tp check_mii_busy; // wait for write to finish |
end |
begin |
// wait for serial bus to become active |
wait(Mdio_IO !== 1'bz); |
// count transfer length |
while(Mdio_IO !== 1'bz) |
begin |
@(posedge Mdc_O); |
#Tp cnt = cnt + 1; |
end |
end |
join |
// check transfer length |
if (i2) // without preamble |
begin |
if (cnt != 33) // at this value Mdio_IO is HIGH Z |
begin |
test_fail("Write request did not proceed correctly, while SCAN STOP command was written"); |
fail = fail + 1; |
end |
end |
else // with preamble |
begin |
if (cnt != 65) // at this value Mdio_IO is HIGH Z |
begin |
test_fail("Write request did not proceed correctly, while SCAN STOP command was written"); |
fail = fail + 1; |
end |
end |
// check the BUSY signal to see if the bus is still IDLE |
for (i1 = 0; i1 < 8; i1 = i1 + 1) |
check_mii_busy; // wait for bus to become idle |
|
// try normal write or read after write was finished |
#Tp cnt = 0; |
if (i3 == 0) // write after write |
begin |
phy_data = {8'h7A, (i[7:0] + 1)}; |
// write request |
#Tp mii_write_req(phy_addr, reg_addr, phy_data); |
// wait for serial bus to become active |
wait(Mdio_IO !== 1'bz); |
// count transfer length |
while(Mdio_IO !== 1'bz) |
begin |
@(posedge Mdc_O); |
#Tp cnt = cnt + 1; |
end |
@(posedge Mdc_O); |
// read request |
#Tp mii_read_req(phy_addr, reg_addr); |
check_mii_busy; // wait for read to finish |
// read and check data |
wbm_read(`ETH_MIIRX_DATA, tmp_data , 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (phy_data !== tmp_data) |
begin |
test_fail("Data was not correctly written into OR read from PHY register - control register"); |
fail = fail + 1; |
end |
end |
else // read after write |
begin |
// read request |
#Tp mii_read_req(phy_addr, reg_addr); |
// wait for serial bus to become active |
wait(Mdio_IO !== 1'bz); |
// count transfer length |
while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) ) |
begin |
@(posedge Mdc_O); |
#Tp cnt = cnt + 1; |
end |
@(posedge Mdc_O); |
check_mii_busy; // wait for read to finish |
// read and check data |
wbm_read(`ETH_MIIRX_DATA, tmp_data , 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (phy_data !== tmp_data) |
begin |
test_fail("Data was not correctly written into OR read from PHY register - control register"); |
fail = fail + 1; |
end |
end |
// check if transfer was a proper length |
if (i2) // without preamble |
begin |
if (cnt != 33) // at this value Mdio_IO is HIGH Z |
begin |
test_fail("New request did not proceed correctly, after write request"); |
fail = fail + 1; |
end |
end |
else // with preamble |
begin |
if (cnt != 65) // at this value Mdio_IO is HIGH Z |
begin |
test_fail("New request did not proceed correctly, after write request"); |
fail = fail + 1; |
end |
end |
end |
#Tp; |
// set delay of writing the command |
if (i2) // without preamble |
begin |
case(i) |
0, 1: i = i + 1; |
18, 19, 20, 21, 22, |
23, 24, 25, 26, 27, |
28, 29, 30, 31, 32, |
33, 34, 35: i = i + 1; |
36: i = 80; |
default: i = 18; |
endcase |
end |
else // with preamble |
begin |
case(i) |
0, 1: i = i + 1; |
50, 51, 52, 53, 54, |
55, 56, 57, 58, 59, |
60, 61, 62, 63, 64, |
65, 66, 67: i = i + 1; |
68: i = 80; |
default: i = 50; |
endcase |
end |
@(posedge wb_clk); |
end |
end |
// set PHY to normal mode |
#Tp eth_phy.preamble_suppresed(0); |
// MII mode register |
wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if(fail == 0) |
test_ok; |
else |
fail = 0; |
end |
|
|
//////////////////////////////////////////////////////////////////// |
//// //// |
//// Test busy and nvalid status durations during write (with //// |
//// and without preamble) //// |
//// //// |
//////////////////////////////////////////////////////////////////// |
if (test_num == 11) // |
begin |
// TEST 11: BUSY AND NVALID STATUS DURATIONS DURING WRITE ( WITH AND WITHOUT PREAMBLE ) |
test_name = "TEST 11: BUSY AND NVALID STATUS DURATIONS DURING WRITE ( WITH AND WITHOUT PREAMBLE )"; |
`TIME; $display(" TEST 11: BUSY AND NVALID STATUS DURATIONS DURING WRITE ( WITH AND WITHOUT PREAMBLE )"); |
|
reset_mii; // reset MII |
// set link up, if it wasn't due to previous tests, since there weren't PHY registers |
#Tp eth_phy.link_up_down(1); |
// set the MII |
clk_div = 64; |
mii_set_clk_div(clk_div[7:0]); |
// set address |
reg_addr = 5'h1; // status register |
phy_addr = 5'h1; // correct PHY address |
|
for (i = 0; i <= 1; i = i + 1) |
begin |
#Tp eth_phy.preamble_suppresed(i); |
// MII mode register |
wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i, 8'h0}) | (`ETH_MIIMODER_CLKDIV & clk_div), |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
@(posedge Mdc_O); |
// write request |
#Tp mii_write_req(phy_addr, reg_addr, 16'h5A5A); |
// read data from MII status register - Busy and Nvalid bits |
wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
|
// check MII IO signal and Busy and Nvalid bits |
if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck |
begin |
test_fail("Testbench error - read was to late, Mdio_IO is not HIGH Z - set higher clock divider"); |
if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0) |
begin |
test_fail("Busy signal was not set while MII IO signal is not HIGH Z anymore - 1. read"); |
fail = fail + 1; |
end |
if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0) |
begin |
test_fail("Nvalid signal was set during write"); |
fail = fail + 1; |
end |
end |
else // Busy bit should already be set to '1', due to reads from MII status register |
begin |
if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0) |
begin |
test_fail("Busy signal should be set after write, due to reads from MII status register"); |
fail = fail + 1; |
end |
if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0) |
begin |
test_fail("Nvalid signal was set during write"); |
fail = fail + 1; |
end |
end |
|
// wait for serial bus to become active |
wait(Mdio_IO !== 1'bz); |
// count transfer bits |
if (i) |
begin |
repeat(32) @(posedge Mdc_O); |
end |
else |
begin |
repeat(64) @(posedge Mdc_O); |
end |
// read data from MII status register - Busy and Nvalid bits |
wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
|
// check MII IO signal and Busy and Nvalid bits |
if (Mdio_IO === 1'bz) // Mdio_IO should not be HIGH Z here - testbench selfcheck |
begin |
test_fail("Testbench error - read was to late, Mdio_IO is HIGH Z - set higher clock divider"); |
if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0) |
begin |
test_fail("Busy signal should be set while MII IO signal is not active anymore"); |
fail = fail + 1; |
end |
if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0) |
begin |
test_fail("Nvalid signal was set during write"); |
fail = fail + 1; |
end |
end |
else // Busy bit should still be set to '1' |
begin |
if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0) |
begin |
test_fail("Busy signal should be set while MII IO signal not HIGH Z"); |
fail = fail + 1; |
end |
if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0) |
begin |
test_fail("Nvalid signal was set during write"); |
fail = fail + 1; |
end |
end |
|
// wait for next negative clock edge |
@(negedge Mdc_O); |
// read data from MII status register - Busy and Nvalid bits |
wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
|
// check MII IO signal and Busy and Nvalid bits |
if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck |
begin |
test_fail("Testbench error - read was to early, Mdio_IO is not HIGH Z - set higher clock divider"); |
if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0) |
begin |
test_fail("Busy signal was not set while MII IO signal is not HIGH Z"); |
fail = fail + 1; |
end |
if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0) |
begin |
test_fail("Nvalid signal was set during write"); |
fail = fail + 1; |
end |
end |
else // Busy bit should still be set to '1' |
begin |
if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0) |
begin |
test_fail("Busy signal should be set after MII IO signal become HIGH Z"); |
fail = fail + 1; |
end |
if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0) |
begin |
test_fail("Nvalid signal was set during write"); |
fail = fail + 1; |
end |
end |
|
// wait for Busy to become inactive |
i1 = 0; |
while (i1 <= 2) |
begin |
// wait for next positive clock edge |
@(posedge Mdc_O); |
// read data from MII status register - Busy and Nvalid bits |
wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
|
// check MII IO signal and Busy and Nvalid bits |
if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck |
begin |
test_fail("Testbench error - read was to early, Mdio_IO is not HIGH Z - set higher clock divider"); |
if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0) |
begin |
test_fail("Busy signal was not set while MII IO signal is not HIGH Z"); |
fail = fail + 1; |
end |
if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0) |
begin |
test_fail("Nvalid signal was set during write"); |
fail = fail + 1; |
end |
end |
else // wait for Busy bit to be set to '0' |
begin |
if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0) |
begin |
i1 = 3; // end of Busy checking |
end |
else |
begin |
if (i1 == 2) |
begin |
test_fail("Busy signal should be cleared after 2 periods after MII IO signal become HIGH Z"); |
fail = fail + 1; |
end |
#Tp i1 = i1 + 1; |
end |
if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0) |
begin |
test_fail("Nvalid signal was set after write"); |
fail = fail + 1; |
end |
end |
end |
end |
// set PHY to normal mode |
#Tp eth_phy.preamble_suppresed(0); |
// MII mode register |
wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if(fail == 0) |
test_ok; |
else |
fail = 0; |
end |
|
|
//////////////////////////////////////////////////////////////////// |
//// //// |
//// Test busy and nvalid status durations during write (with //// |
//// and without preamble) //// |
//// //// |
//////////////////////////////////////////////////////////////////// |
if (test_num == 12) // |
begin |
// TEST 12: BUSY AND NVALID STATUS DURATIONS DURING READ ( WITH AND WITHOUT PREAMBLE ) |
test_name = "TEST 12: BUSY AND NVALID STATUS DURATIONS DURING READ ( WITH AND WITHOUT PREAMBLE )"; |
`TIME; $display(" TEST 12: BUSY AND NVALID STATUS DURATIONS DURING READ ( WITH AND WITHOUT PREAMBLE )"); |
|
reset_mii; // reset MII |
// set link up, if it wasn't due to previous tests, since there weren't PHY registers |
#Tp eth_phy.link_up_down(1); |
// set the MII |
clk_div = 64; |
mii_set_clk_div(clk_div[7:0]); |
// set address |
reg_addr = 5'h1; // status register |
phy_addr = 5'h1; // correct PHY address |
|
for (i = 0; i <= 1; i = i + 1) |
begin |
#Tp eth_phy.preamble_suppresed(i); |
// MII mode register |
wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i, 8'h0}) | (`ETH_MIIMODER_CLKDIV & clk_div), |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
@(posedge Mdc_O); |
// read request |
#Tp mii_read_req(phy_addr, reg_addr); |
// read data from MII status register - Busy and Nvalid bits |
wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
|
// check MII IO signal and Busy and Nvalid bits |
if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck |
begin |
test_fail("Testbench error - read was to late, Mdio_IO is not HIGH Z - set higher clock divider"); |
if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0) |
begin |
test_fail("Busy signal was not set while MII IO signal is not HIGH Z anymore - 1. read"); |
fail = fail + 1; |
end |
if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0) |
begin |
test_fail("Nvalid signal was set during read"); |
fail = fail + 1; |
end |
end |
else // Busy bit should already be set to '1', due to reads from MII status register |
begin |
if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0) |
begin |
test_fail("Busy signal should be set after read, due to reads from MII status register"); |
fail = fail + 1; |
end |
if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0) |
begin |
test_fail("Nvalid signal was set during read"); |
fail = fail + 1; |
end |
end |
|
// wait for serial bus to become active |
wait(Mdio_IO !== 1'bz); |
// count transfer bits |
if (i) |
begin |
repeat(31) @(posedge Mdc_O); |
end |
else |
begin |
repeat(63) @(posedge Mdc_O); |
end |
// wait for next negative clock edge |
@(negedge Mdc_O); |
// read data from MII status register - Busy and Nvalid bits |
wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
|
// check MII IO signal and Busy and Nvalid bits |
if (Mdio_IO === 1'bz) // Mdio_IO should not be HIGH Z here - testbench selfcheck |
begin |
test_fail("Testbench error - read was to late, Mdio_IO is HIGH Z - set higher clock divider"); |
if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0) |
begin |
test_fail("Busy signal should be set while MII IO signal is not active anymore"); |
fail = fail + 1; |
end |
if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0) |
begin |
test_fail("Nvalid signal was set during read"); |
fail = fail + 1; |
end |
end |
else // Busy bit should still be set to '1' |
begin |
if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0) |
begin |
test_fail("Busy signal should be set while MII IO signal not HIGH Z"); |
fail = fail + 1; |
end |
if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0) |
begin |
test_fail("Nvalid signal was set during read"); |
fail = fail + 1; |
end |
end |
|
// wait for next positive clock edge |
@(posedge Mdc_O); |
// read data from MII status register - Busy and Nvalid bits |
wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
|
// check MII IO signal and Busy and Nvalid bits |
if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck |
begin |
test_fail("Testbench error - read was to early, Mdio_IO is not HIGH Z - set higher clock divider"); |
if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0) |
begin |
test_fail("Busy signal was not set while MII IO signal is not HIGH Z"); |
fail = fail + 1; |
end |
if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0) |
begin |
test_fail("Nvalid signal was set during read"); |
fail = fail + 1; |
end |
end |
else // Busy bit should still be set to '1' |
begin |
if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0) |
begin |
test_fail("Busy signal should be set after MII IO signal become HIGH Z"); |
fail = fail + 1; |
end |
if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0) |
begin |
test_fail("Nvalid signal was set during read"); |
fail = fail + 1; |
end |
end |
|
// wait for Busy to become inactive |
i1 = 0; |
while (i1 <= 2) |
begin |
// wait for next positive clock edge |
@(posedge Mdc_O); |
// read data from MII status register - Busy and Nvalid bits |
wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
|
// check MII IO signal and Busy and Nvalid bits |
if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck |
begin |
test_fail("Testbench error - read was to early, Mdio_IO is not HIGH Z - set higher clock divider"); |
if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0) |
begin |
test_fail("Busy signal was not set while MII IO signal is not HIGH Z"); |
fail = fail + 1; |
end |
if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0) |
begin |
test_fail("Nvalid signal was set during read"); |
fail = fail + 1; |
end |
end |
else // wait for Busy bit to be set to '0' |
begin |
if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0) |
begin |
i1 = 3; // end of Busy checking |
end |
else |
begin |
if (i1 == 2) |
begin |
test_fail("Busy signal should be cleared after 2 periods after MII IO signal become HIGH Z"); |
fail = fail + 1; |
end |
#Tp i1 = i1 + 1; |
end |
if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0) |
begin |
test_fail("Nvalid signal was set after read"); |
fail = fail + 1; |
end |
end |
end |
end |
// set PHY to normal mode |
#Tp eth_phy.preamble_suppresed(0); |
// MII mode register |
wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if(fail == 0) |
test_ok; |
else |
fail = 0; |
end |
|
|
//////////////////////////////////////////////////////////////////// |
//// //// |
//// Test busy and nvalid status durations during scan (with //// |
//// and without preamble) //// |
//// //// |
//////////////////////////////////////////////////////////////////// |
if (test_num == 13) // |
begin |
// TEST 13: BUSY AND NVALID STATUS DURATIONS DURING SCAN ( WITH AND WITHOUT PREAMBLE ) |
test_name = "TEST 13: BUSY AND NVALID STATUS DURATIONS DURING SCAN ( WITH AND WITHOUT PREAMBLE )"; |
`TIME; $display(" TEST 13: BUSY AND NVALID STATUS DURATIONS DURING SCAN ( WITH AND WITHOUT PREAMBLE )"); |
|
reset_mii; // reset MII |
// set link up, if it wasn't due to previous tests, since there weren't PHY registers |
#Tp eth_phy.link_up_down(1); |
// set the MII |
clk_div = 64; |
mii_set_clk_div(clk_div[7:0]); |
// set address |
reg_addr = 5'h1; // status register |
phy_addr = 5'h1; // correct PHY address |
|
for (i = 0; i <= 1; i = i + 1) |
begin |
#Tp eth_phy.preamble_suppresed(i); |
// MII mode register |
wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i, 8'h0}) | (`ETH_MIIMODER_CLKDIV & clk_div), |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
@(posedge Mdc_O); |
// scan request |
#Tp mii_scan_req(phy_addr, reg_addr); |
// read data from MII status register - Busy and Nvalid bits |
wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
|
// check MII IO signal and Busy and Nvalid bits |
if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck |
begin |
test_fail("Testbench error - read was to late, Mdio_IO is not HIGH Z - set higher clock divider"); |
if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0) |
begin |
test_fail("Busy signal was not set while MII IO signal is not HIGH Z anymore - 1. read"); |
fail = fail + 1; |
end |
if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0) |
begin |
test_fail("Nvalid signal was not set while MII IO signal is not HIGH Z anymore - 1. read"); |
fail = fail + 1; |
end |
end |
else // Busy bit should already be set to '1', due to reads from MII status register |
begin |
if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0) |
begin |
test_fail("Busy signal should be set after scan, due to reads from MII status register"); |
fail = fail + 1; |
end |
if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0) |
begin |
test_fail("Nvalid signal should be set after scan, due to reads from MII status register"); |
fail = fail + 1; |
end |
end |
|
// wait for serial bus to become active |
wait(Mdio_IO !== 1'bz); |
// count transfer bits |
if (i) |
begin |
repeat(21) @(posedge Mdc_O); |
end |
else |
begin |
repeat(53) @(posedge Mdc_O); |
end |
// stop scan |
#Tp mii_scan_finish; // finish scan operation |
|
// wait for next positive clock edge |
repeat(10) @(posedge Mdc_O); |
// read data from MII status register - Busy and Nvalid bits |
wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
|
// check MII IO signal and Busy and Nvalid bits |
if (Mdio_IO === 1'bz) // Mdio_IO should not be HIGH Z here - testbench selfcheck |
begin |
test_fail("Testbench error - read was to late, Mdio_IO is HIGH Z - set higher clock divider"); |
if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0) |
begin |
test_fail("Busy signal should be set while MII IO signal is not active anymore"); |
fail = fail + 1; |
end |
// Nvalid signal can be cleared here - it is still Testbench error |
end |
else // Busy bit should still be set to '1', Nvalid bit should still be set to '1' |
begin |
if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0) |
begin |
test_fail("Busy signal should be set while MII IO signal not HIGH Z"); |
fail = fail + 1; |
end |
if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0) |
begin |
test_fail("Nvalid signal should be set while MII IO signal not HIGH Z"); |
fail = fail + 1; |
end |
end |
|
// wait for next negative clock edge |
@(negedge Mdc_O); |
// read data from MII status register - Busy and Nvalid bits |
wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
|
// check MII IO signal and Busy and Nvalid bits |
if (Mdio_IO === 1'bz) // Mdio_IO should not be HIGH Z here - testbench selfcheck |
begin |
test_fail("Testbench error - read was to late, Mdio_IO is HIGH Z - set higher clock divider"); |
if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0) |
begin |
test_fail("Busy signal should be set while MII IO signal is not active anymore"); |
fail = fail + 1; |
end |
// Nvalid signal can be cleared here - it is still Testbench error |
end |
else // Busy bit should still be set to '1', Nvalid bit should still be set to '1' |
begin |
if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0) |
begin |
test_fail("Busy signal should be set while MII IO signal not HIGH Z"); |
fail = fail + 1; |
end |
if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0) |
begin |
test_fail("Nvalid signal should be set while MII IO signal not HIGH Z"); |
fail = fail + 1; |
end |
end |
|
// wait for next negative clock edge |
@(posedge Mdc_O); |
// read data from MII status register - Busy and Nvalid bits |
wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
|
// check MII IO signal and Busy and Nvalid bits |
if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck |
begin |
test_fail("Testbench error - read was to early, Mdio_IO is not HIGH Z - set higher clock divider"); |
if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0) |
begin |
test_fail("Busy signal was not set while MII IO signal is not HIGH Z"); |
fail = fail + 1; |
end |
if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0) |
begin |
test_fail("Nvalid signal was not set while MII IO signal is not HIGH Z"); |
fail = fail + 1; |
end |
end |
else // Busy bit should still be set to '1', Nvalid bit can be set to '0' |
begin |
if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0) |
begin |
test_fail("Busy signal should be set after MII IO signal become HIGH Z"); |
fail = fail + 1; |
end |
if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0) |
begin |
i2 = 1; // check finished |
end |
else |
begin |
i2 = 0; // check must continue |
end |
end |
|
// wait for Busy to become inactive |
i1 = 0; |
while ((i1 <= 2) || (i2 == 0)) |
begin |
// wait for next positive clock edge |
@(posedge Mdc_O); |
// read data from MII status register - Busy and Nvalid bits |
wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
|
// check MII IO signal and Busy and Nvalid bits |
if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck |
begin |
test_fail("Testbench error - read was to early, Mdio_IO is not HIGH Z - set higher clock divider"); |
if (i1 <= 2) |
begin |
if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0) |
begin |
test_fail("Busy signal was not set while MII IO signal is not HIGH Z"); |
fail = fail + 1; |
end |
end |
if (i2 == 0) |
begin |
if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0) |
begin |
test_fail("Nvalid signal was not set while MII IO signal is not HIGH Z"); |
fail = fail + 1; |
end |
end |
end |
else // wait for Busy bit to be set to '0' |
begin |
if (i1 <= 2) |
begin |
if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0) |
begin |
i1 = 3; // end of Busy checking |
end |
else |
begin |
if (i1 == 2) |
begin |
test_fail("Busy signal should be cleared after 2 periods after MII IO signal become HIGH Z"); |
fail = fail + 1; |
end |
#Tp i1 = i1 + 1; |
end |
end |
if (i2 == 0) |
begin |
if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0) |
begin |
i2 = 1; |
end |
else |
begin |
test_fail("Nvalid signal should be cleared after MII IO signal become HIGH Z"); |
fail = fail + 1; |
end |
end |
end |
end |
end |
// set PHY to normal mode |
#Tp eth_phy.preamble_suppresed(0); |
// MII mode register |
wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if(fail == 0) |
test_ok; |
else |
fail = 0; |
end |
|
|
//////////////////////////////////////////////////////////////////// |
//// //// |
//// Test scan status from phy with detecting link-fail bit //// |
//// (with and without preamble) //// |
//// //// |
//////////////////////////////////////////////////////////////////// |
if (test_num == 14) // |
begin |
// TEST 14: SCAN STATUS FROM PHY WITH DETECTING LINK-FAIL BIT ( WITH AND WITHOUT PREAMBLE ) |
test_name = "TEST 14: SCAN STATUS FROM PHY WITH DETECTING LINK-FAIL BIT ( WITH AND WITHOUT PREAMBLE )"; |
`TIME; $display(" TEST 14: SCAN STATUS FROM PHY WITH DETECTING LINK-FAIL BIT ( WITH AND WITHOUT PREAMBLE )"); |
|
reset_mii; // reset MII |
// set link up, if it wasn't due to previous tests, since there weren't PHY registers |
#Tp eth_phy.link_up_down(1); |
// set MII speed |
clk_div = 6; |
mii_set_clk_div(clk_div[7:0]); |
// set address |
reg_addr = 5'h1; // status register |
phy_addr = 5'h1; // correct PHY address |
|
// read request |
#Tp mii_read_req(phy_addr, reg_addr); |
check_mii_busy; // wait for read to finish |
// read data from PHY status register - remember LINK-UP status |
wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
|
for (i = 0; i <= 1; i = i + 1) |
begin |
#Tp eth_phy.preamble_suppresed(i); |
// MII mode register |
wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i, 8'h0}) | (`ETH_MIIMODER_CLKDIV & clk_div), |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (i) |
begin |
// change saved data when preamble is suppressed |
#Tp tmp_data = tmp_data | 16'h0040; // put bit 6 to ONE |
end |
|
// scan request |
#Tp mii_scan_req(phy_addr, reg_addr); |
check_mii_scan_valid; // wait for scan to make first data valid |
|
fork |
begin |
repeat(2) @(posedge Mdc_O); |
// read data from PHY status register |
wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (phy_data !== tmp_data) |
begin |
test_fail("Data was not correctly scaned from status register"); |
fail = fail + 1; |
end |
// read data from MII status register |
wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (phy_data[0] !== 1'b0) |
begin |
test_fail("Link FAIL bit was set in the MII status register"); |
fail = fail + 1; |
end |
end |
begin |
// Completely check second scan |
#Tp cnt = 0; |
// wait for serial bus to become active - second scan |
wait(Mdio_IO !== 1'bz); |
// count transfer length |
while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i == 0)) || ((cnt == 15) && (i == 1)) ) |
begin |
@(posedge Mdc_O); |
#Tp cnt = cnt + 1; |
end |
// check transfer length |
if (i) // without preamble |
begin |
if (cnt != 33) // at this value Mdio_IO is HIGH Z |
begin |
test_fail("Second scan request did not proceed correctly"); |
fail = fail + 1; |
end |
end |
else // with preamble |
begin |
if (cnt != 65) // at this value Mdio_IO is HIGH Z |
begin |
test_fail("Second scan request did not proceed correctly"); |
fail = fail + 1; |
end |
end |
end |
join |
// check third to fifth scans |
for (i3 = 0; i3 <= 2; i3 = i3 + 1) |
begin |
fork |
begin |
repeat(2) @(posedge Mdc_O); |
// read data from PHY status register |
wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (phy_data !== tmp_data) |
begin |
test_fail("Data was not correctly scaned from status register"); |
fail = fail + 1; |
end |
// read data from MII status register |
wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (phy_data[0] !== 1'b0) |
begin |
test_fail("Link FAIL bit was set in the MII status register"); |
fail = fail + 1; |
end |
if (i3 == 2) // after fourth scan read |
begin |
@(posedge Mdc_O); |
// change saved data |
#Tp tmp_data = tmp_data & 16'hFFFB; // put bit 3 to ZERO |
// set link down |
#Tp eth_phy.link_up_down(0); |
end |
end |
begin |
// Completely check scans |
#Tp cnt = 0; |
// wait for serial bus to become active - second scan |
wait(Mdio_IO !== 1'bz); |
// count transfer length |
while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i == 0)) || ((cnt == 15) && (i == 1)) ) |
begin |
@(posedge Mdc_O); |
#Tp cnt = cnt + 1; |
end |
// check transfer length |
if (i) // without preamble |
begin |
if (cnt != 33) // at this value Mdio_IO is HIGH Z |
begin |
test_fail("Fifth scan request did not proceed correctly"); |
fail = fail + 1; |
end |
end |
else // with preamble |
begin |
if (cnt != 65) // at this value Mdio_IO is HIGH Z |
begin |
test_fail("Fifth scan request did not proceed correctly"); |
fail = fail + 1; |
end |
end |
end |
join |
end |
|
fork |
begin |
repeat(2) @(posedge Mdc_O); |
// read data from PHY status register |
wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (phy_data !== tmp_data) |
begin |
test_fail("Data was not correctly scaned from status register"); |
fail = fail + 1; |
end |
// read data from MII status register |
wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (phy_data[0] === 1'b0) |
begin |
test_fail("Link FAIL bit was not set in the MII status register"); |
fail = fail + 1; |
end |
// wait to see if data stayed latched |
repeat(4) @(posedge Mdc_O); |
// read data from PHY status register |
wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (phy_data !== tmp_data) |
begin |
test_fail("Data was not latched correctly in status register"); |
fail = fail + 1; |
end |
// read data from MII status register |
wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (phy_data[0] === 1'b0) |
begin |
test_fail("Link FAIL bit was not set in the MII status register"); |
fail = fail + 1; |
end |
// change saved data |
#Tp tmp_data = tmp_data | 16'h0004; // put bit 2 to ONE |
// set link up |
#Tp eth_phy.link_up_down(1); |
end |
begin |
// Wait for sixth scan |
// wait for serial bus to become active - sixth scan |
wait(Mdio_IO !== 1'bz); |
// wait for serial bus to become inactive - turn-around cycle in sixth scan |
wait(Mdio_IO === 1'bz); |
// wait for serial bus to become active - end of turn-around cycle in sixth scan |
wait(Mdio_IO !== 1'bz); |
// wait for serial bus to become inactive - end of sixth scan |
wait(Mdio_IO === 1'bz); |
end |
join |
|
@(posedge Mdc_O); |
// read data from PHY status register |
wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (phy_data !== tmp_data) |
begin |
test_fail("Data was not correctly scaned from status register"); |
fail = fail + 1; |
end |
// read data from MII status register |
wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (phy_data[0] !== 1'b0) |
begin |
test_fail("Link FAIL bit was set in the MII status register"); |
fail = fail + 1; |
end |
// wait to see if data stayed latched |
repeat(4) @(posedge Mdc_O); |
// read data from PHY status register |
wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (phy_data !== tmp_data) |
begin |
test_fail("Data was not correctly scaned from status register"); |
fail = fail + 1; |
end |
// read data from MII status register |
wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (phy_data[0] !== 1'b0) |
begin |
test_fail("Link FAIL bit was set in the MII status register"); |
fail = fail + 1; |
end |
|
// STOP SCAN |
#Tp mii_scan_finish; // finish scan operation |
#Tp check_mii_busy; // wait for scan to finish |
end |
// set PHY to normal mode |
#Tp eth_phy.preamble_suppresed(0); |
// MII mode register |
wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if(fail == 0) |
test_ok; |
else |
fail = 0; |
end |
|
|
//////////////////////////////////////////////////////////////////// |
//// //// |
//// Test scan status from phy with sliding link-fail bit //// |
//// (with and without preamble) //// |
//// //// |
//////////////////////////////////////////////////////////////////// |
if (test_num == 15) // |
begin |
// TEST 15: SCAN STATUS FROM PHY WITH SLIDING LINK-FAIL BIT ( WITH AND WITHOUT PREAMBLE ) |
test_name = "TEST 15: SCAN STATUS FROM PHY WITH SLIDING LINK-FAIL BIT ( WITH AND WITHOUT PREAMBLE )"; |
`TIME; $display(" TEST 15: SCAN STATUS FROM PHY WITH SLIDING LINK-FAIL BIT ( WITH AND WITHOUT PREAMBLE )"); |
|
// set address |
reg_addr = 5'h1; // status register |
phy_addr = 5'h1; // correct PHY address |
|
// read request |
#Tp mii_read_req(phy_addr, reg_addr); |
check_mii_busy; // wait for read to finish |
// read data from PHY status register - remember LINK-UP status |
wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
|
for (i2 = 0; i2 <= 1; i2 = i2 + 1) // choose preamble or not |
begin |
#Tp eth_phy.preamble_suppresed(i2); |
// MII mode register |
#Tp wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i2, 8'h0}), 4'hF, 1, wbm_init_waits, |
wbm_subseq_waits); |
if (i2) |
begin |
// change saved data when preamble is suppressed |
#Tp tmp_data = tmp_data | 16'h0040; // put bit 6 to ONE |
end |
|
i = 0; |
while (i < 80) // delay for sliding of LinkFail bit |
begin |
// first there are two scans |
#Tp cnt = 0; |
// scan request |
#Tp mii_scan_req(phy_addr, reg_addr); |
#Tp check_mii_scan_valid; // wait for scan to make first data valid |
|
// check second scan |
fork |
begin |
repeat(4) @(posedge Mdc_O); |
// read data from PHY status register |
wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (phy_data !== tmp_data) |
begin |
test_fail("Second data was not correctly scaned from status register"); |
fail = fail + 1; |
end |
// read data from MII status register |
wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (phy_data[0] !== 1'b0) |
begin |
test_fail("Link FAIL bit was set in the MII status register"); |
fail = fail + 1; |
end |
end |
begin |
// Completely check scan |
#Tp cnt = 0; |
// wait for serial bus to become active - second scan |
wait(Mdio_IO !== 1'bz); |
// count transfer length |
while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) ) |
begin |
@(posedge Mdc_O); |
#Tp cnt = cnt + 1; |
end |
// check transfer length |
if (i2) // without preamble |
begin |
if (cnt != 33) // at this value Mdio_IO is HIGH Z |
begin |
test_fail("Second scan request did not proceed correctly"); |
fail = fail + 1; |
end |
end |
else // with preamble |
begin |
if (cnt != 65) // at this value Mdio_IO is HIGH Z |
begin |
test_fail("Second scan request did not proceed correctly"); |
fail = fail + 1; |
end |
end |
end |
join |
// reset counter |
#Tp cnt = 0; |
// SLIDING LINK DOWN and CHECK |
fork |
begin |
// set link down |
repeat(i) @(posedge Mdc_O); |
// set link down |
#Tp eth_phy.link_up_down(0); |
end |
begin |
// check data in MII registers after each scan in this fork statement |
if (i2) // without preamble |
wait (cnt == 32); |
else // with preamble |
wait (cnt == 64); |
repeat(3) @(posedge Mdc_O); |
// read data from PHY status register |
wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if ( ((i < 49) && !i2) || ((i < 17) && i2) ) |
begin |
if (phy_data !== (tmp_data & 16'hFFFB)) // bit 3 is ZERO |
begin |
test_fail("Third data was not correctly scaned from status register"); |
fail = fail + 1; |
end |
end |
else |
begin |
if (phy_data !== tmp_data) |
begin |
test_fail("Third data was not correctly scaned from status register"); |
fail = fail + 1; |
end |
end |
// read data from MII status register |
wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if ( ((i < 49) && !i2) || ((i < 17) && i2) ) |
begin |
if (phy_data[0] === 1'b0) |
begin |
test_fail("Link FAIL bit was not set in the MII status register"); |
fail = fail + 1; |
end |
end |
else |
begin |
if (phy_data[0] !== 1'b0) |
begin |
test_fail("Link FAIL bit was set in the MII status register"); |
fail = fail + 1; |
end |
end |
end |
begin |
// check length |
for (i3 = 0; i3 <= 1; i3 = i3 + 1) // two scans |
begin |
#Tp cnt = 0; |
// wait for serial bus to become active if there is more than one scan |
wait(Mdio_IO !== 1'bz); |
// count transfer length |
while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) ) |
begin |
@(posedge Mdc_O); |
#Tp cnt = cnt + 1; |
end |
// check transfer length |
if (i2) // without preamble |
begin |
if (cnt != 33) // at this value Mdio_IO is HIGH Z |
begin |
test_fail("3. or 4. scan request did not proceed correctly, while SCAN STOP was written"); |
fail = fail + 1; |
end |
end |
else // with preamble |
begin |
if (cnt != 65) // at this value Mdio_IO is HIGH Z |
begin |
test_fail("3. or 4. scan request did not proceed correctly, while SCAN STOP was written"); |
fail = fail + 1; |
end |
end |
end |
end |
join |
// reset counter |
#Tp cnt = 0; |
// check fifth scan and data from fourth scan |
fork |
begin |
repeat(2) @(posedge Mdc_O); |
// read data from PHY status register |
wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (phy_data !== (tmp_data & 16'hFFFB)) // bit 3 is ZERO |
begin |
test_fail("4. data was not correctly scaned from status register"); |
fail = fail + 1; |
end |
// read data from MII status register |
wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (phy_data[0] === 1'b0) |
begin |
test_fail("Link FAIL bit was not set in the MII status register"); |
fail = fail + 1; |
end |
end |
begin |
// Completely check intermediate scan |
#Tp cnt = 0; |
// wait for serial bus to become active - second scan |
wait(Mdio_IO !== 1'bz); |
// count transfer length |
while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) ) |
begin |
@(posedge Mdc_O); |
#Tp cnt = cnt + 1; |
end |
// check transfer length |
if (i2) // without preamble |
begin |
if (cnt != 33) // at this value Mdio_IO is HIGH Z |
begin |
test_fail("Fifth scan request did not proceed correctly"); |
fail = fail + 1; |
end |
end |
else // with preamble |
begin |
if (cnt != 65) // at this value Mdio_IO is HIGH Z |
begin |
test_fail("Fifth scan request did not proceed correctly"); |
fail = fail + 1; |
end |
end |
end |
join |
// reset counter |
#Tp cnt = 0; |
// SLIDING LINK UP and CHECK |
fork |
begin |
// set link up |
repeat(i) @(posedge Mdc_O); |
// set link up |
#Tp eth_phy.link_up_down(1); |
end |
begin |
// check data in MII registers after each scan in this fork statement |
repeat(2) @(posedge Mdc_O); |
if (i2) // without preamble |
wait (cnt == 32); |
else // with preamble |
wait (cnt == 64); |
repeat(3) @(posedge Mdc_O); |
// read data from PHY status register |
wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if ( ((i < 49) && !i2) || ((i < 17) && i2) ) |
begin |
if (phy_data !== tmp_data) |
begin |
test_fail("6. data was not correctly scaned from status register"); |
fail = fail + 1; |
end |
end |
else |
begin |
if (phy_data !== (tmp_data & 16'hFFFB)) // bit 3 is ZERO |
begin |
test_fail("6. data was not correctly scaned from status register"); |
fail = fail + 1; |
end |
end |
// read data from MII status register |
wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if ( ((i < 49) && !i2) || ((i < 17) && i2) ) |
begin |
if (phy_data[0] !== 1'b0) |
begin |
test_fail("Link FAIL bit was set in the MII status register"); |
fail = fail + 1; |
end |
end |
else |
begin |
if (phy_data[0] === 1'b0) |
begin |
test_fail("Link FAIL bit was not set in the MII status register"); |
fail = fail + 1; |
end |
end |
end |
begin |
// check length |
for (i3 = 0; i3 <= 1; i3 = i3 + 1) // two scans |
begin |
#Tp cnt = 0; |
// wait for serial bus to become active if there is more than one scan |
wait(Mdio_IO !== 1'bz); |
// count transfer length |
while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) ) |
begin |
@(posedge Mdc_O); |
#Tp cnt = cnt + 1; |
end |
// check transfer length |
if (i2) // without preamble |
begin |
if (cnt != 33) // at this value Mdio_IO is HIGH Z |
begin |
test_fail("Scan request did not proceed correctly, while SCAN STOP was written"); |
fail = fail + 1; |
end |
end |
else // with preamble |
begin |
if (cnt != 65) // at this value Mdio_IO is HIGH Z |
begin |
test_fail("Scan request did not proceed correctly, while SCAN STOP was written"); |
fail = fail + 1; |
end |
end |
end |
end |
join |
// check last scan |
repeat(4) @(posedge Mdc_O); |
// read data from PHY status register |
wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (phy_data !== tmp_data) |
begin |
test_fail("7. data was not correctly scaned from status register"); |
fail = fail + 1; |
end |
// read data from MII status register |
wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (phy_data[0] !== 1'b0) |
begin |
test_fail("Link FAIL bit was set in the MII status register"); |
fail = fail + 1; |
end |
|
#Tp mii_scan_finish; // finish scan operation |
#Tp check_mii_busy; // wait for scan to finish |
#Tp; |
// set delay of writing the command |
if (i2) // without preamble |
begin |
case(i) |
0, 1, 2, 3, 4: i = i + 1; |
13, 14, 15, 16, 17, |
18, 19, 20, 21, 22, |
23, 24, 25, 26, 27, |
28, 29, 30, 31, 32, |
33, 34, 35: i = i + 1; |
36: i = 80; |
default: i = 13; |
endcase |
end |
else // with preamble |
begin |
case(i) |
0, 1, 2, 3, 4: i = i + 1; |
45, 46, 47, 48, 49, |
50, 51, 52, 53, 54, |
55, 56, 57, 58, 59, |
60, 61, 62, 63, 64, |
65, 66, 67: i = i + 1; |
68: i = 80; |
default: i = 45; |
endcase |
end |
@(posedge wb_clk); |
#Tp; |
end |
end |
// set PHY to normal mode |
#Tp eth_phy.preamble_suppresed(0); |
// MII mode register |
wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if(fail == 0) |
test_ok; |
else |
fail = 0; |
end |
|
|
//////////////////////////////////////////////////////////////////// |
//// //// |
//// Test sliding stop scan command immediately after scan //// |
//// request (with and without preamble) //// |
//// //// |
//////////////////////////////////////////////////////////////////// |
if (test_num == 16) // |
begin |
// TEST 16: SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER SCAN REQUEST ( WITH AND WITHOUT PREAMBLE ) |
test_name = "TEST 16: SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER SCAN REQUEST ( WITH AND WITHOUT PREAMBLE )"; |
`TIME; |
$display(" TEST 16: SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER SCAN REQUEST ( WITH AND WITHOUT PREAMBLE )"); |
|
for (i2 = 0; i2 <= 1; i2 = i2 + 1) // choose preamble or not |
begin |
#Tp eth_phy.preamble_suppresed(i2); |
// MII mode register |
wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i2, 8'h0}), 4'hF, 1, wbm_init_waits, |
wbm_subseq_waits); |
i = 0; |
cnt = 0; |
while (i < 80) // delay for sliding of writing a STOP SCAN command |
begin |
for (i3 = 0; i3 <= 1; i3 = i3 + 1) // choose read or write after scan will be finished |
begin |
// set address |
reg_addr = 5'h0; // control register |
phy_addr = 5'h1; // correct PHY address |
cnt = 0; |
// scan request |
#Tp mii_scan_req(phy_addr, reg_addr); |
fork |
begin |
repeat(i) @(posedge Mdc_O); |
// write command 0x0 into MII command register |
// MII command written while scan in progress |
wbm_write(`ETH_MIICOMMAND, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
@(posedge wb_clk); |
#Tp check_mii_busy; // wait for scan to finish |
@(posedge wb_clk); |
disable check; |
end |
begin: check |
// wait for serial bus to become active |
wait(Mdio_IO !== 1'bz); |
// count transfer length |
while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) ) |
begin |
@(posedge Mdc_O); |
#Tp cnt = cnt + 1; |
end |
// check transfer length |
if (i2) // without preamble |
begin |
if (cnt != 33) // at this value Mdio_IO is HIGH Z |
begin |
test_fail("First scan request did not proceed correctly, while SCAN STOP was written"); |
fail = fail + 1; |
end |
end |
else // with preamble |
begin |
if (cnt != 65) // at this value Mdio_IO is HIGH Z |
begin |
test_fail("First scan request did not proceed correctly, while SCAN STOP was written"); |
fail = fail + 1; |
end |
end |
cnt = 0; |
// wait for serial bus to become active if there is more than one scan |
wait(Mdio_IO !== 1'bz); |
// count transfer length |
while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) ) |
begin |
@(posedge Mdc_O); |
#Tp cnt = cnt + 1; |
end |
// check transfer length |
if (i2) // without preamble |
begin |
if (cnt != 33) // at this value Mdio_IO is HIGH Z |
begin |
test_fail("First scan request did not proceed correctly, while SCAN STOP was written"); |
fail = fail + 1; |
end |
end |
else // with preamble |
begin |
if (cnt != 65) // at this value Mdio_IO is HIGH Z |
begin |
test_fail("First scan request did not proceed correctly, while SCAN STOP was written"); |
fail = fail + 1; |
end |
end |
end |
join |
// check the BUSY signal to see if the bus is still IDLE |
for (i1 = 0; i1 < 8; i1 = i1 + 1) |
check_mii_busy; // wait for bus to become idle |
|
// try normal write or read after scan was finished |
phy_data = {8'h7D, (i[7:0] + 1)}; |
cnt = 0; |
if (i3 == 0) // write after scan |
begin |
// write request |
#Tp mii_write_req(phy_addr, reg_addr, phy_data); |
// wait for serial bus to become active |
wait(Mdio_IO !== 1'bz); |
// count transfer length |
while(Mdio_IO !== 1'bz) |
begin |
@(posedge Mdc_O); |
#Tp cnt = cnt + 1; |
end |
@(posedge Mdc_O); |
// read request |
#Tp mii_read_req(phy_addr, reg_addr); |
check_mii_busy; // wait for read to finish |
// read and check data |
wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (phy_data !== tmp_data) |
begin |
test_fail("Data was not correctly written into OR read from PHY register - control register"); |
fail = fail + 1; |
end |
end |
else // read after scan |
begin |
// read request |
#Tp mii_read_req(phy_addr, reg_addr); |
// wait for serial bus to become active |
wait(Mdio_IO !== 1'bz); |
// count transfer length |
while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) ) |
begin |
@(posedge Mdc_O); |
#Tp cnt = cnt + 1; |
end |
@(posedge Mdc_O); |
check_mii_busy; // wait for read to finish |
// read and check data |
wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (phy_data !== tmp_data) |
begin |
test_fail("Data was not correctly written into OR read from PHY register - control register"); |
fail = fail + 1; |
end |
end |
// check if transfer was a proper length |
if (i2) // without preamble |
begin |
if (cnt != 33) // at this value Mdio_IO is HIGH Z |
begin |
test_fail("New request did not proceed correctly, after scan request"); |
fail = fail + 1; |
end |
end |
else // with preamble |
begin |
if (cnt != 65) // at this value Mdio_IO is HIGH Z |
begin |
test_fail("New request did not proceed correctly, after scan request"); |
fail = fail + 1; |
end |
end |
end |
#Tp; |
// set delay of writing the command |
if (i2) // without preamble |
begin |
case(i) |
0, 1: i = i + 1; |
18, 19, 20, 21, 22, |
23, 24, 25, 26, 27, |
28, 29, 30, 31, 32, |
33, 34, 35: i = i + 1; |
36: i = 80; |
default: i = 18; |
endcase |
end |
else // with preamble |
begin |
case(i) |
0, 1: i = i + 1; |
50, 51, 52, 53, 54, |
55, 56, 57, 58, 59, |
60, 61, 62, 63, 64, |
65, 66, 67: i = i + 1; |
68: i = 80; |
default: i = 50; |
endcase |
end |
@(posedge wb_clk); |
end |
end |
// set PHY to normal mode |
#Tp eth_phy.preamble_suppresed(0); |
// MII mode register |
wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if(fail == 0) |
test_ok; |
else |
fail = 0; |
end |
|
|
//////////////////////////////////////////////////////////////////// |
//// //// |
//// Test sliding stop scan command after 2. scan (with and //// |
//// without preamble) //// |
//// //// |
//////////////////////////////////////////////////////////////////// |
if (test_num == 17) // |
begin |
// TEST 17: SLIDING STOP SCAN COMMAND AFTER 2. SCAN ( WITH AND WITHOUT PREAMBLE ) |
test_name = "TEST 17: SLIDING STOP SCAN COMMAND AFTER 2. SCAN ( WITH AND WITHOUT PREAMBLE )"; |
`TIME; $display(" TEST 17: SLIDING STOP SCAN COMMAND AFTER 2. SCAN ( WITH AND WITHOUT PREAMBLE )"); |
|
for (i2 = 0; i2 <= 1; i2 = i2 + 1) // choose preamble or not |
begin |
#Tp eth_phy.preamble_suppresed(i2); |
// MII mode register |
wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i2, 8'h0}), 4'hF, 1, wbm_init_waits, |
wbm_subseq_waits); |
|
i = 0; |
cnt = 0; |
while (i < 80) // delay for sliding of writing a STOP SCAN command |
begin |
for (i3 = 0; i3 <= 1; i3 = i3 + 1) // choose read or write after scan will be finished |
begin |
// first there are two scans |
// set address |
reg_addr = 5'h0; // control register |
phy_addr = 5'h1; // correct PHY address |
cnt = 0; |
// scan request |
#Tp mii_scan_req(phy_addr, reg_addr); |
// wait and check first 2 scans |
begin |
// wait for serial bus to become active |
wait(Mdio_IO !== 1'bz); |
// count transfer length |
while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) ) |
begin |
@(posedge Mdc_O); |
#Tp cnt = cnt + 1; |
end |
// check transfer length |
if (i2) // without preamble |
begin |
if (cnt != 33) // at this value Mdio_IO is HIGH Z |
begin |
test_fail("First scan request did not proceed correctly, while SCAN STOP was written"); |
fail = fail + 1; |
end |
end |
else // with preamble |
begin |
if (cnt != 65) // at this value Mdio_IO is HIGH Z |
begin |
test_fail("First scan request did not proceed correctly, while SCAN STOP was written"); |
fail = fail + 1; |
end |
end |
cnt = 0; |
// wait for serial bus to become active if there is more than one scan |
wait(Mdio_IO !== 1'bz); |
// count transfer length |
while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) ) |
begin |
@(posedge Mdc_O); |
#Tp cnt = cnt + 1; |
end |
// check transfer length |
if (i2) // without preamble |
begin |
if (cnt != 33) // at this value Mdio_IO is HIGH Z |
begin |
test_fail("First scan request did not proceed correctly, while SCAN STOP was written"); |
fail = fail + 1; |
end |
end |
else // with preamble |
begin |
if (cnt != 65) // at this value Mdio_IO is HIGH Z |
begin |
test_fail("First scan request did not proceed correctly, while SCAN STOP was written"); |
fail = fail + 1; |
end |
end |
end |
|
// reset counter |
cnt = 0; |
fork |
begin |
repeat(i) @(posedge Mdc_O); |
// write command 0x0 into MII command register |
// MII command written while scan in progress |
wbm_write(`ETH_MIICOMMAND, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
@(posedge wb_clk); |
#Tp check_mii_busy; // wait for scan to finish |
@(posedge wb_clk); |
disable check_3; |
end |
begin: check_3 |
// wait for serial bus to become active |
wait(Mdio_IO !== 1'bz); |
// count transfer length |
while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) ) |
begin |
@(posedge Mdc_O); |
#Tp cnt = cnt + 1; |
end |
// check transfer length |
if (i2) // without preamble |
begin |
if (cnt != 33) // at this value Mdio_IO is HIGH Z |
begin |
test_fail("First scan request did not proceed correctly, while SCAN STOP was written"); |
fail = fail + 1; |
end |
end |
else // with preamble |
begin |
if (cnt != 65) // at this value Mdio_IO is HIGH Z |
begin |
test_fail("First scan request did not proceed correctly, while SCAN STOP was written"); |
fail = fail + 1; |
end |
end |
cnt = 0; |
// wait for serial bus to become active if there is more than one scan |
wait(Mdio_IO !== 1'bz); |
// count transfer length |
while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) ) |
begin |
@(posedge Mdc_O); |
#Tp cnt = cnt + 1; |
end |
// check transfer length |
if (i2) // without preamble |
begin |
if (cnt != 33) // at this value Mdio_IO is HIGH Z |
begin |
test_fail("First scan request did not proceed correctly, while SCAN STOP was written"); |
fail = fail + 1; |
end |
end |
else // with preamble |
begin |
if (cnt != 65) // at this value Mdio_IO is HIGH Z |
begin |
test_fail("First scan request did not proceed correctly, while SCAN STOP was written"); |
fail = fail + 1; |
end |
end |
end |
join |
// check the BUSY signal to see if the bus is still IDLE |
for (i1 = 0; i1 < 8; i1 = i1 + 1) |
check_mii_busy; // wait for bus to become idle |
|
// try normal write or read after scan was finished |
phy_data = {8'h7D, (i[7:0] + 1)}; |
cnt = 0; |
if (i3 == 0) // write after scan |
begin |
// write request |
#Tp mii_write_req(phy_addr, reg_addr, phy_data); |
// wait for serial bus to become active |
wait(Mdio_IO !== 1'bz); |
// count transfer length |
while(Mdio_IO !== 1'bz) |
begin |
@(posedge Mdc_O); |
#Tp cnt = cnt + 1; |
end |
@(posedge Mdc_O); |
// read request |
#Tp mii_read_req(phy_addr, reg_addr); |
check_mii_busy; // wait for read to finish |
// read and check data |
wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (phy_data !== tmp_data) |
begin |
test_fail("Data was not correctly written into OR read from PHY register - control register"); |
fail = fail + 1; |
end |
end |
else // read after scan |
begin |
// read request |
#Tp mii_read_req(phy_addr, reg_addr); |
// wait for serial bus to become active |
wait(Mdio_IO !== 1'bz); |
// count transfer length |
while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) ) |
begin |
@(posedge Mdc_O); |
#Tp cnt = cnt + 1; |
end |
@(posedge Mdc_O); |
check_mii_busy; // wait for read to finish |
// read and check data |
wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (phy_data !== tmp_data) |
begin |
test_fail("Data was not correctly written into OR read from PHY register - control register"); |
fail = fail + 1; |
end |
end |
// check if transfer was a proper length |
if (i2) // without preamble |
begin |
if (cnt != 33) // at this value Mdio_IO is HIGH Z |
begin |
test_fail("New request did not proceed correctly, after scan request"); |
fail = fail + 1; |
end |
end |
else // with preamble |
begin |
if (cnt != 65) // at this value Mdio_IO is HIGH Z |
begin |
test_fail("New request did not proceed correctly, after scan request"); |
fail = fail + 1; |
end |
end |
end |
#Tp; |
// set delay of writing the command |
if (i2) // without preamble |
begin |
case(i) |
0, 1: i = i + 1; |
18, 19, 20, 21, 22, |
23, 24, 25, 26, 27, |
28, 29, 30, 31, 32, |
33, 34, 35: i = i + 1; |
36: i = 80; |
default: i = 18; |
endcase |
end |
else // with preamble |
begin |
case(i) |
0, 1: i = i + 1; |
50, 51, 52, 53, 54, |
55, 56, 57, 58, 59, |
60, 61, 62, 63, 64, |
65, 66, 67: i = i + 1; |
68: i = 80; |
default: i = 50; |
endcase |
end |
@(posedge wb_clk); |
end |
end |
// set PHY to normal mode |
#Tp eth_phy.preamble_suppresed(0); |
// MII mode register |
wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if(fail == 0) |
test_ok; |
else |
fail = 0; |
end |
|
end // for (test_num=start_task; test_num <= end_task; test_num=test_num+1) |
|
end |
endtask // test_mii |
|
|
task test_mac_full_duplex_transmit; |
input [31:0] start_task; |
input [31:0] end_task; |
integer bit_start_1; |
integer bit_end_1; |
integer bit_start_2; |
integer bit_end_2; |
integer num_of_reg; |
integer num_of_frames; |
integer num_of_bd; |
integer i_addr; |
integer i_data; |
integer i_length; |
integer tmp_len; |
integer tmp_bd; |
integer tmp_bd_num; |
integer tmp_data; |
integer tmp_ipgt; |
integer test_num; |
reg [31:0] tx_bd_num; |
reg [((`MAX_BLK_SIZE * 32) - 1):0] burst_data; |
reg [((`MAX_BLK_SIZE * 32) - 1):0] burst_tmp_data; |
integer i; |
integer i1; |
integer i2; |
integer i3; |
integer fail; |
integer speed; |
reg no_underrun; |
reg frame_started; |
reg frame_ended; |
reg wait_for_frame; |
reg [31:0] addr; |
reg [31:0] data; |
reg [31:0] tmp; |
reg [ 7:0] st_data; |
reg [15:0] max_tmp; |
reg [15:0] min_tmp; |
|
begin |
// MAC FULL DUPLEX TRANSMIT TEST |
test_heading("MAC FULL DUPLEX TRANSMIT TEST"); |
$display(" "); |
$display("MAC FULL DUPLEX TRANSMIT TEST"); |
fail = 0; |
|
// reset MAC registers |
hard_reset; |
// reset MAC and MII LOGIC with soft reset |
//reset_mac; |
//reset_mii; |
// set wb slave response |
wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries); |
|
/* |
TASKS for set and control TX buffer descriptors (also send packet - set_tx_bd_ready): |
------------------------------------------------------------------------------------- |
set_tx_bd |
(tx_bd_num_start[6:0], tx_bd_num_end[6:0], len[15:0], irq, pad, crc, txpnt[31:0]); |
set_tx_bd_wrap |
(tx_bd_num_end[6:0]); |
set_tx_bd_ready |
(tx_bd_num_start[6:0], tx_bd_num_end[6:0]); |
check_tx_bd |
(tx_bd_num_start[6:0], tx_bd_status[31:0]); |
clear_tx_bd |
(tx_bd_num_start[6:0], tx_bd_num_end[6:0]); |
|
TASKS for set and control RX buffer descriptors: |
------------------------------------------------ |
set_rx_bd |
(rx_bd_num_strat[6:0], rx_bd_num_end[6:0], irq, rxpnt[31:0]); |
set_rx_bd_wrap |
(rx_bd_num_end[6:0]); |
set_rx_bd_empty |
(rx_bd_num_strat[6:0], rx_bd_num_end[6:0]); |
check_rx_bd |
(rx_bd_num_end[6:0], rx_bd_status); |
clear_rx_bd |
(rx_bd_num_strat[6:0], rx_bd_num_end[6:0]); |
|
TASKS for set and check TX packets: |
----------------------------------- |
set_tx_packet |
(txpnt[31:0], len[15:0], eth_start_data[7:0]); |
check_tx_packet |
(txpnt_wb[31:0], txpnt_phy[31:0], len[15:0], failure[31:0]); |
|
TASKS for set and check RX packets: |
----------------------------------- |
set_rx_packet |
(rxpnt[31:0], len[15:0], plus_nibble, d_addr[47:0], s_addr[47:0], type_len[15:0], start_data[7:0]); |
check_rx_packet |
(rxpnt_phy[31:0], rxpnt_wb[31:0], len[15:0], plus_nibble, successful_nibble, failure[31:0]); |
|
TASKS for append and check CRC to/of TX packet: |
----------------------------------------------- |
append_tx_crc |
(txpnt_wb[31:0], len[15:0], negated_crc); |
check_tx_crc |
(txpnt_phy[31:0], len[15:0], negated_crc, failure[31:0]); |
|
TASK for append CRC to RX packet (CRC is checked together with check_rx_packet): |
-------------------------------------------------------------------------------- |
append_rx_crc |
(rxpnt_phy[31:0], len[15:0], plus_nibble, negated_crc); |
*/ |
|
////////////////////////////////////////////////////////////////////// |
//// //// |
//// test_mac_full_duplex_transmit: //// |
//// //// |
//// 0: Test no transmit when all buffers are RX ( 10Mbps ). //// |
//// 1: Test no transmit when all buffers are RX ( 100Mbps ). //// |
//// 2: Test transmit packets form MINFL to MAXFL sizes at //// |
//// one TX buffer decriptor ( 10Mbps ). //// |
//// 3: Test transmit packets form MINFL to MAXFL sizes at //// |
//// one TX buffer decriptor ( 100Mbps ). //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
for (test_num = start_task; test_num <= end_task; test_num = test_num + 1) |
begin |
|
//////////////////////////////////////////////////////////////////// |
//// //// |
//// Test no transmit when all buffers are RX ( 10Mbps ). //// |
//// //// |
//////////////////////////////////////////////////////////////////// |
if (test_num == 0) // Test no transmit when all buffers are RX ( 10Mbps ). |
begin |
// TEST 0: NO TRANSMIT WHEN ALL BUFFERS ARE RX ( 10Mbps ) |
test_name = "TEST 0: NO TRANSMIT WHEN ALL BUFFERS ARE RX ( 10Mbps )"; |
`TIME; $display(" TEST 0: NO TRANSMIT WHEN ALL BUFFERS ARE RX ( 10Mbps )"); |
|
// unmask interrupts |
wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY | |
`ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// set all buffer descriptors to RX - must be set before TX enable |
wait (wbm_working == 0); |
wbm_write(`ETH_TX_BD_NUM, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// enable TX, set full-duplex mode, padding and CRC appending |
wait (wbm_working == 0); |
wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN, |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
|
// write to phy's control register for 10Mbps |
#Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10 |
#Tp eth_phy.control_bit8_0 = 9'h1_00; // bit 6 reset - (10/100), bit 8 set - FD |
speed = 10; |
|
i = 0; |
while (i < 128) |
begin |
for (i1 = 0; i1 <= i; i1 = i1 + 1) |
begin |
set_tx_packet((`MEMORY_BASE + (i1 * 200)), 100, 0); |
set_tx_bd(i1, i1, 100, 1'b1, 1'b1, 1'b1, (`MEMORY_BASE + (i1 * 200))); |
end |
set_tx_bd_wrap(i); |
fork |
begin |
set_tx_bd_ready(0, i); |
repeat(20) @(negedge mtx_clk); |
#1 disable check_tx_en10; |
end |
begin: check_tx_en10 |
wait (MTxEn === 1'b1); |
test_fail("Tramsmit should not start at all"); |
fail = fail + 1; |
`TIME; $display("*E Transmit of %d packets should not start at all - active MTxEn", i); |
end |
join |
for (i2 = 0; i2 < 20; i2 = i2 + 1) |
begin |
check_tx_bd(0, tmp); |
#1; |
if (tmp[15] === 1'b0) |
begin |
test_fail("Tramsmit should not start at all"); |
fail = fail + 1; |
`TIME; $display("*E Transmit of %d packets should not start at all - ready is 0", i); |
end |
if (tmp[8:0] !== 0) |
begin |
test_fail("Tramsmit should not be finished since it should not start at all"); |
fail = fail + 1; |
`TIME; $display("*E Transmit of should not be finished since it should not start at all"); |
end |
@(posedge wb_clk); |
end |
wait (wbm_working == 0); |
wbm_read(`ETH_INT, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (tmp[6:0] !== 0) |
begin |
test_fail("Tramsmit should not get INT since it should not start at all"); |
fail = fail + 1; |
`TIME; $display("*E Transmit of should not get INT since it should not start at all"); |
end |
clear_tx_bd(0, i); |
if ((i < 5) || (i > 124)) |
i = i + 1; |
else |
i = i + 120; |
end |
// disable TX |
wait (wbm_working == 0); |
wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN, |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if(fail == 0) |
test_ok; |
else |
fail = 0; |
end |
|
|
//////////////////////////////////////////////////////////////////// |
//// //// |
//// Test no transmit when all buffers are RX ( 100Mbps ). //// |
//// //// |
//////////////////////////////////////////////////////////////////// |
if (test_num == 1) // Test no transmit when all buffers are RX ( 100Mbps ). |
begin |
// TEST 1: NO TRANSMIT WHEN ALL BUFFERS ARE RX ( 100Mbps ) |
test_name = "TEST 1: NO TRANSMIT WHEN ALL BUFFERS ARE RX ( 100Mbps )"; |
`TIME; $display(" TEST 1: NO TRANSMIT WHEN ALL BUFFERS ARE RX ( 100Mbps )"); |
|
// unmask interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY | |
`ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// set all buffer descriptors to RX - must be set before TX enable |
wait (wbm_working == 0); |
wbm_write(`ETH_TX_BD_NUM, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// enable TX, set full-duplex mode, padding and CRC appending |
wait (wbm_working == 0); |
wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN, |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
|
// write to phy's control register for 100Mbps |
#Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 set - speed 100 |
#Tp eth_phy.control_bit8_0 = 9'h1_00; // bit 6 reset - (10/100), bit 8 set - FD |
speed = 100; |
|
i = 0; |
while (i < 128) |
begin |
for (i1 = 0; i1 <= i; i1 = i1 + 1) |
begin |
set_tx_packet((`MEMORY_BASE + (i1 * 200)), 100, 0); |
set_tx_bd(i1, i1, 100, 1'b1, 1'b1, 1'b1, (`MEMORY_BASE + (i1 * 200))); |
end |
set_tx_bd_wrap(i); |
fork |
begin |
set_tx_bd_ready(0, i); |
repeat(20) @(negedge mtx_clk); |
#1 disable check_tx_en100; |
end |
begin: check_tx_en100 |
wait (MTxEn === 1'b1); |
test_fail("Tramsmit should not start at all"); |
fail = fail + 1; |
`TIME; $display("*E Transmit of %d packets should not start at all - active MTxEn", i); |
end |
join |
for (i2 = 0; i2 < 20; i2 = i2 + 1) |
begin |
check_tx_bd(0, tmp); |
#1; |
if (tmp[15] === 1'b0) |
begin |
test_fail("Tramsmit should not start at all"); |
fail = fail + 1; |
`TIME; $display("*E Transmit of %d packets should not start at all - ready is 0", i); |
end |
if (tmp[8:0] !== 0) |
begin |
test_fail("Tramsmit should not be finished since it should not start at all"); |
fail = fail + 1; |
`TIME; $display("*E Transmit of should not be finished since it should not start at all"); |
end |
@(posedge wb_clk); |
end |
wait (wbm_working == 0); |
wbm_read(`ETH_INT, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if (tmp[6:0] !== 0) |
begin |
test_fail("Tramsmit should not get INT since it should not start at all"); |
fail = fail + 1; |
`TIME; $display("*E Transmit of should not get INT since it should not start at all"); |
end |
clear_tx_bd(0, i); |
if ((i < 5) || (i > 124)) |
i = i + 1; |
else |
i = i + 120; |
end |
// disable TX |
wait (wbm_working == 0); |
wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN, |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if(fail == 0) |
test_ok; |
else |
fail = 0; |
end |
|
|
//////////////////////////////////////////////////////////////////// |
//// //// |
//// Test transmit packets form MINFL to MAXFL sizes at //// |
//// one TX buffer decriptor ( 10Mbps ). //// |
//// //// |
//////////////////////////////////////////////////////////////////// |
if (test_num == 2) // without and with padding |
begin |
// TEST 2: TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT ONE TX BD ( 10Mbps ) |
test_name = "TEST 2: TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT ONE TX BD ( 10Mbps )"; |
`TIME; $display(" TEST 2: TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT ONE TX BD ( 10Mbps )"); |
|
max_tmp = 0; |
min_tmp = 0; |
// set one TX buffer descriptor - must be set before TX enable |
wait (wbm_working == 0); |
wbm_write(`ETH_TX_BD_NUM, 32'h1, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// enable TX, set full-duplex mode, NO padding and CRC appending |
wait (wbm_working == 0); |
wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN, |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// prepare two packets of MAXFL length |
wait (wbm_working == 0); |
wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC |
min_tmp = tmp[31:16]; |
st_data = 8'h01; |
set_tx_packet(`MEMORY_BASE, (max_tmp), st_data); // length without CRC |
st_data = 8'h10; |
set_tx_packet((`MEMORY_BASE + max_tmp), (max_tmp), st_data); // length without CRC |
// check WB INT signal |
if (wb_int !== 1'b0) |
begin |
test_fail("WB INT signal should not be set"); |
fail = fail + 1; |
end |
|
// write to phy's control register for 10Mbps |
#Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10 |
#Tp eth_phy.control_bit8_0 = 9'h1_00; // bit 6 reset - (10/100), bit 8 set - FD |
speed = 10; |
|
i_length = (min_tmp - 4); |
while (i_length <= (max_tmp - 4)) |
begin |
// choose generating carrier sense and collision for first and last 64 lengths of frames |
case (i_length[1:0]) |
2'h0: // Interrupt is generated |
begin |
// enable interrupt generation |
set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, (`MEMORY_BASE + i_length[1:0])); |
// unmask interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY | |
`ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// not detect carrier sense in FD and no collision |
eth_phy.carrier_sense_tx_fd_detect(0); |
eth_phy.collision(0); |
end |
2'h1: // Interrupt is not generated |
begin |
// enable interrupt generation |
set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, ((`MEMORY_BASE + i_length[1:0]) + max_tmp)); |
// mask interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// detect carrier sense in FD and no collision |
eth_phy.carrier_sense_tx_fd_detect(1); |
eth_phy.collision(0); |
end |
2'h2: // Interrupt is not generated |
begin |
// disable interrupt generation |
set_tx_bd(0, 0, i_length, 1'b0, 1'b1, 1'b1, (`MEMORY_BASE + i_length[1:0])); |
// unmask interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY | |
`ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// not detect carrier sense in FD and set collision |
eth_phy.carrier_sense_tx_fd_detect(0); |
eth_phy.collision(1); |
end |
default: // 2'h3: // Interrupt is not generated |
begin |
// disable interrupt generation |
set_tx_bd(0, 0, i_length, 1'b0, 1'b1, 1'b1, ((`MEMORY_BASE + i_length[1:0]) + max_tmp)); |
// mask interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// detect carrier sense in FD and set collision |
eth_phy.carrier_sense_tx_fd_detect(1); |
eth_phy.collision(1); |
end |
endcase |
eth_phy.set_tx_mem_addr(max_tmp); |
// set wrap bit |
set_tx_bd_wrap(0); |
set_tx_bd_ready(0, 0); |
#1 check_tx_bd(0, data); |
|
|
if (i_length < min_tmp) // just first four |
begin |
while (data[15] === 1) |
begin |
#1 check_tx_bd(0, data); |
@(posedge wb_clk); |
end |
repeat (1) @(posedge wb_clk); |
end |
else if (i_length > (max_tmp - 8)) // just last four |
begin |
tmp = 0; |
wait (MTxEn === 1'b1); // start transmit |
while (tmp < (i_length - 20)) |
begin |
#1 tmp = tmp + 1; |
@(posedge wb_clk); |
end |
#1 check_tx_bd(0, data); |
while (data[15] === 1) |
begin |
#1 check_tx_bd(0, data); |
@(posedge wb_clk); |
end |
repeat (1) @(posedge wb_clk); |
end |
else |
begin |
wait (MTxEn === 1'b1); // start transmit |
#1 check_tx_bd(0, data); |
if (data[15] !== 1) |
begin |
test_fail("Wrong buffer descriptor's ready bit read out from MAC"); |
fail = fail + 1; |
end |
wait (MTxEn === 1'b0); // end transmit |
while (data[15] === 1) |
begin |
#1 check_tx_bd(0, data); |
@(posedge wb_clk); |
end |
repeat (1) @(posedge wb_clk); |
end |
|
repeat(5) @(posedge mtx_clk); // Wait some time so PHY stores the CRC |
|
// check length of a PACKET |
if (eth_phy.tx_len != (i_length + 4)) |
begin |
test_fail("Wrong length of the packet out from MAC"); |
fail = fail + 1; |
end |
// checking in the following if statement is performed only for first and last 64 lengths |
if ( ((i_length + 4) <= (min_tmp + 64)) || ((i_length + 4) > (max_tmp - 64)) ) |
begin |
// check transmitted TX packet data |
if (i_length[0] == 0) |
begin |
check_tx_packet((`MEMORY_BASE + i_length[1:0]), max_tmp, i_length, tmp); |
end |
else |
begin |
check_tx_packet(((`MEMORY_BASE + i_length[1:0]) + max_tmp), max_tmp, i_length, tmp); |
end |
if (tmp > 0) |
begin |
test_fail("Wrong data of the transmitted packet"); |
fail = fail + 1; |
end |
// check transmited TX packet CRC |
check_tx_crc(max_tmp, i_length, 1'b0, tmp); // length without CRC |
|
if (tmp > 0) |
begin |
test_fail("Wrong CRC of the transmitted packet"); |
fail = fail + 1; |
end |
end |
// check WB INT signal |
if (i_length[1:0] == 2'h0) |
begin |
if (wb_int !== 1'b1) |
begin |
`TIME; $display("*E WB INT signal should be set"); |
test_fail("WB INT signal should be set"); |
fail = fail + 1; |
end |
end |
else |
begin |
if (wb_int !== 1'b0) |
begin |
`TIME; $display("*E WB INT signal should not be set"); |
test_fail("WB INT signal should not be set"); |
fail = fail + 1; |
end |
end |
// check TX buffer descriptor of a packet |
check_tx_bd(0, data); |
if (i_length[1] == 1'b0) // interrupt enabled |
begin |
if (data[15:0] !== 16'h7800) |
begin |
`TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]); |
test_fail("TX buffer descriptor status is not correct"); |
fail = fail + 1; |
end |
end |
else // interrupt not enabled |
begin |
if (data[15:0] !== 16'h3800) |
begin |
`TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]); |
test_fail("TX buffer descriptor status is not correct"); |
fail = fail + 1; |
end |
end |
// clear TX buffer descriptor |
clear_tx_bd(0, 0); |
// check interrupts |
wait (wbm_working == 0); |
wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if ((i_length[1:0] == 2'h0) || (i_length[1:0] == 2'h1)) |
begin |
if ((data & `ETH_INT_TXB) !== 1'b1) |
begin |
`TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data); |
test_fail("Interrupt Transmit Buffer was not set"); |
fail = fail + 1; |
end |
if ((data & (~`ETH_INT_TXB)) !== 0) |
begin |
`TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data); |
test_fail("Other interrupts (except Transmit Buffer) were set"); |
fail = fail + 1; |
end |
end |
else |
begin |
if (data !== 0) |
begin |
`TIME; $display("*E Any of interrupts (except Transmit Buffer) was set, interrupt reg: %0h, len: %0h", data, i_length[1:0]); |
test_fail("Any of interrupts (except Transmit Buffer) was set"); |
fail = fail + 1; |
end |
end |
// clear interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// check WB INT signal |
if (wb_int !== 1'b0) |
begin |
test_fail("WB INT signal should not be set"); |
fail = fail + 1; |
end |
// INTERMEDIATE DISPLAYS |
if ((i_length + 4) == (min_tmp + 64)) |
begin |
// starting length is min_tmp, ending length is (min_tmp + 64) |
$display(" pads appending to packets is NOT selected"); |
$display(" ->packets with lengths from %0d (MINFL) to %0d are checked (length increasing by 1 byte)", |
min_tmp, (min_tmp + 64)); |
// set padding, remain the rest |
wait (wbm_working == 0); |
wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN, |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
end |
else if ((i_length + 4) == (max_tmp - 16)) |
begin |
// starting length is for +128 longer than previous ending length, while ending length is tmp_data |
$display(" pads appending to packets is selected"); |
$display(" ->packets with lengths from %0d to %0d are checked (length increasing by 128 bytes)", |
(min_tmp + 64 + 128), tmp_data); |
// reset padding, remain the rest |
wait (wbm_working == 0); |
wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN, |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
end |
else if ((i_length + 4) == max_tmp) |
begin |
$display(" pads appending to packets is NOT selected"); |
$display(" ->packets with lengths from %0d to %0d (MAXFL) are checked (length increasing by 1 byte)", |
(max_tmp - (4 + 16)), max_tmp); |
end |
// set length (loop variable) |
if ((i_length + 4) < (min_tmp + 64)) |
i_length = i_length + 1; |
else if ( ((i_length + 4) >= (min_tmp + 64)) && ((i_length + 4) <= (max_tmp - 256)) ) |
begin |
i_length = i_length + 128; |
tmp_data = i_length + 4; // last tmp_data is ending length |
end |
else if ( ((i_length + 4) > (max_tmp - 256)) && ((i_length + 4) < (max_tmp - 16)) ) |
i_length = max_tmp - (4 + 16); |
else if ((i_length + 4) >= (max_tmp - 16)) |
i_length = i_length + 1; |
else |
begin |
$display("*E TESTBENCH ERROR - WRONG PARAMETERS IN TESTBENCH"); |
#10 $stop; |
end |
end |
// disable TX |
wait (wbm_working == 0); |
wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN, |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if(fail == 0) |
test_ok; |
else |
fail = 0; |
end |
|
|
//////////////////////////////////////////////////////////////////// |
//// //// |
//// Test transmit packets form MINFL to MAXFL sizes at //// |
//// one TX buffer decriptor ( 100Mbps ). //// |
//// //// |
//////////////////////////////////////////////////////////////////// |
if (test_num == 3) // with and without padding |
begin |
// TEST 3: TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT ONE TX BD ( 100Mbps ) |
test_name = "TEST 3: TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT ONE TX BD ( 100Mbps )"; |
`TIME; $display(" TEST 3: TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT ONE TX BD ( 100Mbps )"); |
|
max_tmp = 0; |
min_tmp = 0; |
// set one TX buffer descriptor - must be set before TX enable |
wait (wbm_working == 0); |
wbm_write(`ETH_TX_BD_NUM, 32'h1, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// enable TX, set full-duplex mode, NO padding and CRC appending |
wait (wbm_working == 0); |
wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN, |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// prepare two packets of MAXFL length |
wait (wbm_working == 0); |
wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC |
min_tmp = tmp[31:16]; |
st_data = 8'h5A; |
set_tx_packet(`MEMORY_BASE, (max_tmp), st_data); // length without CRC |
st_data = 8'h10; |
set_tx_packet((`MEMORY_BASE + max_tmp), (max_tmp), st_data); // length without CRC |
// check WB INT signal |
if (wb_int !== 1'b0) |
begin |
test_fail("WB INT signal should not be set"); |
fail = fail + 1; |
end |
|
// write to phy's control register for 100Mbps |
#Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 set - speed 100 |
#Tp eth_phy.control_bit8_0 = 9'h1_00; // bit 6 reset - (10/100), bit 8 set - FD |
speed = 100; |
|
i_length = (min_tmp - 4); |
while (i_length <= (max_tmp - 4)) |
begin |
// choose generating carrier sense and collision |
case (i_length[1:0]) |
2'h0: // Interrupt is generated |
begin |
// enable interrupt generation |
set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, (`MEMORY_BASE + i_length[1:0])); |
// unmask interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY | |
`ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// not detect carrier sense in FD and no collision |
eth_phy.carrier_sense_tx_fd_detect(0); |
eth_phy.collision(0); |
end |
2'h1: // Interrupt is not generated |
begin |
// enable interrupt generation |
set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, ((`MEMORY_BASE + i_length[1:0]) + max_tmp)); |
// mask interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// detect carrier sense in FD and no collision |
eth_phy.carrier_sense_tx_fd_detect(1); |
eth_phy.collision(0); |
end |
2'h2: // Interrupt is not generated |
begin |
// disable interrupt generation |
set_tx_bd(0, 0, i_length, 1'b0, 1'b1, 1'b1, (`MEMORY_BASE + i_length[1:0])); |
// unmask interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY | |
`ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// not detect carrier sense in FD and set collision |
eth_phy.carrier_sense_tx_fd_detect(0); |
eth_phy.collision(1); |
end |
default: // 2'h3: // Interrupt is not generated |
begin |
// disable interrupt generation |
set_tx_bd(0, 0, i_length, 1'b0, 1'b1, 1'b1, ((`MEMORY_BASE + i_length[1:0]) + max_tmp)); |
// mask interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// detect carrier sense in FD and set collision |
eth_phy.carrier_sense_tx_fd_detect(1); |
eth_phy.collision(1); |
end |
endcase |
eth_phy.set_tx_mem_addr(max_tmp); |
// set wrap bit |
set_tx_bd_wrap(0); |
set_tx_bd_ready(0, 0); |
#1 check_tx_bd(0, data); |
if (i_length < min_tmp) // just first four |
begin |
while (data[15] === 1) |
begin |
#1 check_tx_bd(0, data); |
@(posedge wb_clk); |
end |
repeat (1) @(posedge wb_clk); |
end |
else if (i_length > (max_tmp - 8)) // just last four |
begin |
tmp = 0; |
wait (MTxEn === 1'b1); // start transmit |
while (tmp < (i_length - 20)) |
begin |
#1 tmp = tmp + 1; |
@(posedge wb_clk); |
end |
#1 check_tx_bd(0, data); |
while (data[15] === 1) |
begin |
#1 check_tx_bd(0, data); |
@(posedge wb_clk); |
end |
repeat (1) @(posedge wb_clk); |
end |
else |
begin |
wait (MTxEn === 1'b1); // start transmit |
#1 check_tx_bd(0, data); |
if (data[15] !== 1) |
begin |
test_fail("Wrong buffer descriptor's ready bit read out from MAC"); |
fail = fail + 1; |
end |
wait (MTxEn === 1'b0); // end transmit |
while (data[15] === 1) |
begin |
#1 check_tx_bd(0, data); |
@(posedge wb_clk); |
end |
repeat (1) @(posedge wb_clk); |
end |
// check length of a PACKET |
if (eth_phy.tx_len != (i_length + 4)) |
begin |
test_fail("Wrong length of the packet out from MAC"); |
fail = fail + 1; |
end |
// check transmitted TX packet data |
if (i_length[0] == 0) |
begin |
check_tx_packet((`MEMORY_BASE + i_length[1:0]), max_tmp, i_length, tmp); |
end |
else |
begin |
check_tx_packet(((`MEMORY_BASE + i_length[1:0]) + max_tmp), max_tmp, i_length, tmp); |
end |
if (tmp > 0) |
begin |
test_fail("Wrong data of the transmitted packet"); |
fail = fail + 1; |
end |
// check transmited TX packet CRC |
check_tx_crc(max_tmp, i_length, 1'b0, tmp); // length without CRC |
if (tmp > 0) |
begin |
test_fail("Wrong CRC of the transmitted packet"); |
fail = fail + 1; |
end |
// check WB INT signal |
if (i_length[1:0] == 2'h0) |
begin |
if (wb_int !== 1'b1) |
begin |
`TIME; $display("*E WB INT signal should be set"); |
test_fail("WB INT signal should be set"); |
fail = fail + 1; |
end |
end |
else |
begin |
if (wb_int !== 1'b0) |
begin |
`TIME; $display("*E WB INT signal should not be set"); |
test_fail("WB INT signal should not be set"); |
fail = fail + 1; |
end |
end |
// check TX buffer descriptor of a packet |
check_tx_bd(0, data); |
if (i_length[1] == 1'b0) // interrupt enabled |
begin |
if (data[15:0] !== 16'h7800) |
begin |
`TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]); |
test_fail("TX buffer descriptor status is not correct"); |
fail = fail + 1; |
end |
end |
else // interrupt not enabled |
begin |
if (data[15:0] !== 16'h3800) |
begin |
`TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]); |
test_fail("TX buffer descriptor status is not correct"); |
fail = fail + 1; |
end |
end |
// clear TX buffer descriptor |
clear_tx_bd(0, 0); |
// check interrupts |
wait (wbm_working == 0); |
wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if ((i_length[1:0] == 2'h0) || (i_length[1:0] == 2'h1)) |
begin |
if ((data & `ETH_INT_TXB) !== 1'b1) |
begin |
`TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data); |
test_fail("Interrupt Transmit Buffer was not set"); |
fail = fail + 1; |
end |
if ((data & (~`ETH_INT_TXB)) !== 0) |
begin |
`TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data); |
test_fail("Other interrupts (except Transmit Buffer) were set"); |
fail = fail + 1; |
end |
end |
else |
begin |
if (data !== 0) |
begin |
`TIME; $display("*E Any of interrupts (except Transmit Buffer) was set, interrupt reg: %0h", data); |
test_fail("Any of interrupts (except Transmit Buffer) was set"); |
fail = fail + 1; |
end |
end |
// clear interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// check WB INT signal |
if (wb_int !== 1'b0) |
begin |
test_fail("WB INT signal should not be set"); |
fail = fail + 1; |
end |
// INTERMEDIATE DISPLAYS |
if ((i_length + 4) == (min_tmp + 64)) |
begin |
// starting length is min_tmp, ending length is (min_tmp + 64) |
$display(" pads appending to packets is NOT selected"); |
$display(" ->packets with lengths from %0d (MINFL) to %0d are checked (length increasing by 1 byte)", |
min_tmp, (min_tmp + 64)); |
// set padding, remain the rest |
wait (wbm_working == 0); |
wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN, |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
end |
else if ((i_length + 4) == (max_tmp - 16)) |
begin |
// starting length is for +128 longer than previous ending length, while ending length is tmp_data |
$display(" pads appending to packets is selected"); |
$display(" ->packets with lengths from %0d to %0d are checked (length increasing by 128 bytes)", |
(min_tmp + 64 + 128), tmp_data); |
// reset padding, remain the rest |
wait (wbm_working == 0); |
wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN, |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
end |
else if ((i_length + 4) == max_tmp) |
begin |
$display(" pads appending to packets is NOT selected"); |
$display(" ->packets with lengths from %0d to %0d (MAXFL) are checked (length increasing by 1 byte)", |
(max_tmp - (4 + 16)), max_tmp); |
end |
// set length (loop variable) |
if ((i_length + 4) < (min_tmp + 64)) |
i_length = i_length + 1; |
else if ( ((i_length + 4) >= (min_tmp + 64)) && ((i_length + 4) <= (max_tmp - 256)) ) |
begin |
i_length = i_length + 128; |
tmp_data = i_length + 4; // last tmp_data is ending length |
end |
else if ( ((i_length + 4) > (max_tmp - 256)) && ((i_length + 4) < (max_tmp - 16)) ) |
i_length = max_tmp - (4 + 16); |
else if ((i_length + 4) >= (max_tmp - 16)) |
i_length = i_length + 1; |
else |
begin |
$display("*E TESTBENCH ERROR - WRONG PARAMETERS IN TESTBENCH"); |
#10 $stop; |
end |
end |
// disable TX |
wait (wbm_working == 0); |
wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN, |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if(fail == 0) |
test_ok; |
else |
fail = 0; |
end |
|
|
//////////////////////////////////////////////////////////////////// |
//// //// |
//// Test transmit packets form MINFL to MAXFL sizes at //// |
//// maximum TX buffer decriptors ( 10Mbps ). //// |
//// //// |
//////////////////////////////////////////////////////////////////// |
if (test_num == 4) // without and with padding |
begin |
// TEST 4: TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT MAX TX BDs ( 10Mbps ) |
test_name = "TEST 4: TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT MAX TX BDs ( 10Mbps )"; |
`TIME; $display(" TEST 4: TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT MAX TX BDs ( 10Mbps )"); |
|
// reset MAC registers |
hard_reset; |
// reset MAC and MII LOGIC with soft reset |
// reset_mac; |
// reset_mii; |
// set wb slave response |
wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries); |
|
max_tmp = 0; |
min_tmp = 0; |
num_of_frames = 0; |
num_of_bd = 0; |
// set maximum TX buffer descriptors (128) - must be set before TX enable |
wait (wbm_working == 0); |
wbm_write(`ETH_TX_BD_NUM, 32'h80, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// enable TX, set full-duplex mode, NO padding and CRC appending |
wait (wbm_working == 0); |
wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN, |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// prepare two packets of MAXFL length |
wait (wbm_working == 0); |
wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC |
min_tmp = tmp[31:16]; |
st_data = 8'hA3; |
set_tx_packet(`MEMORY_BASE, (max_tmp), st_data); // length without CRC |
st_data = 8'h81; |
set_tx_packet((`MEMORY_BASE + max_tmp), (max_tmp), st_data); // length without CRC |
// check WB INT signal |
if (wb_int !== 1'b0) |
begin |
test_fail("WB INT signal should not be set"); |
fail = fail + 1; |
end |
|
// write to phy's control register for 10Mbps |
#Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10 |
#Tp eth_phy.control_bit8_0 = 9'h1_00; // bit 6 reset - (10/100), bit 8 set - FD |
speed = 10; |
|
i_length = (min_tmp - 4); |
while (i_length <= (max_tmp - 4)) |
begin |
// choose generating carrier sense and collision |
case (i_length[1:0]) |
2'h0: // Interrupt is generated |
begin |
// Reset_tx_bd nable interrupt generation |
// unmask interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY | |
`ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// not detect carrier sense in FD and no collision |
eth_phy.carrier_sense_tx_fd_detect(0); |
eth_phy.collision(0); |
end |
2'h1: // Interrupt is not generated |
begin |
// set_tx_bd enable interrupt generation |
// mask interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// detect carrier sense in FD and no collision |
eth_phy.carrier_sense_tx_fd_detect(1); |
eth_phy.collision(0); |
end |
2'h2: // Interrupt is not generated |
begin |
// set_tx_bd disable the interrupt generation |
// unmask interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY | |
`ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// not detect carrier sense in FD and set collision |
eth_phy.carrier_sense_tx_fd_detect(0); |
eth_phy.collision(1); |
end |
default: // 2'h3: // Interrupt is not generated |
begin |
// set_tx_bd disable the interrupt generation |
// mask interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// detect carrier sense in FD and set collision |
eth_phy.carrier_sense_tx_fd_detect(1); |
eth_phy.collision(1); |
end |
endcase |
// first destination address on ethernet PHY |
if (i_length[0] == 0) |
eth_phy.set_tx_mem_addr(0); |
else |
eth_phy.set_tx_mem_addr(max_tmp); |
// first 8 frames are transmitted with TX BD 0 (wrap bit on TX BD 0) |
// number of all frames is 154 (146 without first 8) |
if (num_of_frames < 8) |
begin |
case (i_length[1:0]) |
2'h0: // Interrupt is generated |
begin |
// enable interrupt generation |
set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, (`MEMORY_BASE + i_length[1:0])); |
// interrupts are unmasked |
end |
2'h1: // Interrupt is not generated |
begin |
// enable interrupt generation |
set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, ((`MEMORY_BASE + i_length[1:0]) + max_tmp)); |
// interrupts are masked |
end |
2'h2: // Interrupt is not generated |
begin |
// disable interrupt generation |
set_tx_bd(0, 0, i_length, 1'b0, 1'b1, 1'b1, (`MEMORY_BASE + i_length[1:0])); |
// interrupts are unmasked |
end |
default: // 2'h3: // Interrupt is not generated |
begin |
// disable interrupt generation |
set_tx_bd(0, 0, i_length, 1'b0, 1'b1, 1'b1, ((`MEMORY_BASE + i_length[1:0]) + max_tmp)); |
// interrupts are masked |
end |
endcase |
// set wrap bit |
set_tx_bd_wrap(0); |
end |
// after first 8 number of frames, 128 frames form TX BD 0 to 127 will be transmitted |
else if ((num_of_frames - 8) == 0) |
begin |
tmp_len = i_length; // length of frame |
tmp_bd_num = 0; // TX BD number |
while (tmp_bd_num < 128) // (tmp_len <= (max_tmp - 4)) - this is the last frame |
begin |
// if i_length[1] == 0 then enable interrupt generation otherwise disable it |
// if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp |
if (tmp_len[0] == 0) |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + tmp_len[1:0])); |
else |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, ((`MEMORY_BASE + tmp_len[1:0]) + max_tmp)); |
// set length (loop variable) - THE SAME AS AT THE END OF THIS TASK !!! |
if ((tmp_len + 4) < (min_tmp + 128)) |
tmp_len = tmp_len + 1; |
else if ( ((tmp_len + 4) == (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) ) |
tmp_len = 256; |
else if ( ((tmp_len + 4) > (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) ) |
tmp_len = tmp_len + 128; |
else if ( ((tmp_len + 4) > (max_tmp - 256)) && ((tmp_len + 4) < (max_tmp - 16)) ) |
tmp_len = max_tmp - (4 + 16); |
else if ((tmp_len + 4) >= (max_tmp - 16)) |
tmp_len = tmp_len + 1; |
// set TX BD number |
tmp_bd_num = tmp_bd_num + 1; |
end |
// set wrap bit |
set_tx_bd_wrap(127); |
end |
// after 128 + first 8 number of frames, 19 frames form TX BD 0 to 18 will be transmitted |
else if ((num_of_frames - 8) == 20) // 128 |
begin |
tmp_len = tmp_len; // length of frame remaines from previous settings |
tmp_bd_num = 0; // TX BD number |
while (tmp_bd_num < 19) // (tmp_len <= (max_tmp - 4)) - this is the last frame |
begin |
// if i_length[1] == 0 then enable interrupt generation otherwise disable it |
// if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp |
if (tmp_len[0] == 0) |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + tmp_len[1:0])); |
else |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, ((`MEMORY_BASE + tmp_len[1:0]) + max_tmp)); |
// set length (loop variable) - THE SAME AS AT THE END OF THIS TASK !!! |
if ((tmp_len + 4) < (min_tmp + 128)) |
tmp_len = tmp_len + 1; |
else if ( ((tmp_len + 4) == (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) ) |
tmp_len = 256; |
else if ( ((tmp_len + 4) > (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) ) |
tmp_len = tmp_len + 128; |
else if ( ((tmp_len + 4) > (max_tmp - 256)) && ((tmp_len + 4) < (max_tmp - 16)) ) |
tmp_len = max_tmp - (4 + 16); |
else if ((tmp_len + 4) >= (max_tmp - 16)) |
tmp_len = tmp_len + 1; |
// set TX BD number |
tmp_bd_num = tmp_bd_num + 1; |
end |
end |
// set ready bit |
if (num_of_frames < 8) |
set_tx_bd_ready(0, 0); |
else if ((num_of_frames - 8) < 128) |
set_tx_bd_ready((num_of_frames - 8), (num_of_frames - 8)); |
else if ((num_of_frames - 136) < 19) |
set_tx_bd_ready((num_of_frames - 136), (num_of_frames - 136)); |
// CHECK END OF TRANSMITION |
#1 check_tx_bd(num_of_bd, data); |
if (i_length < min_tmp) // just first four |
begin |
while (data[15] === 1) |
begin |
#1 check_tx_bd(num_of_bd, data); |
@(posedge wb_clk); |
end |
repeat (1) @(posedge wb_clk); |
end |
else if (i_length > (max_tmp - 8)) // just last four |
begin |
tmp = 0; |
wait (MTxEn === 1'b1); // start transmit |
while (tmp < (i_length - 20)) |
begin |
#1 tmp = tmp + 1; |
@(posedge wb_clk); |
end |
#1 check_tx_bd(num_of_bd, data); |
while (data[15] === 1) |
begin |
#1 check_tx_bd(num_of_bd, data); |
@(posedge wb_clk); |
end |
repeat (1) @(posedge wb_clk); |
end |
else |
begin |
wait (MTxEn === 1'b1); // start transmit |
#1 check_tx_bd(num_of_bd, data); |
if (data[15] !== 1) |
begin |
test_fail("Wrong buffer descriptor's ready bit read out from MAC"); |
fail = fail + 1; |
end |
wait (MTxEn === 1'b0); // end transmit |
while (data[15] === 1) |
begin |
#1 check_tx_bd(num_of_bd, data); |
@(posedge wb_clk); |
end |
repeat (1) @(posedge wb_clk); |
end |
// check length of a PACKET |
if (eth_phy.tx_len != (i_length + 4)) |
begin |
test_fail("Wrong length of the packet out from MAC"); |
fail = fail + 1; |
end |
// check transmitted TX packet data |
if (i_length[0] == 0) |
begin |
check_tx_packet((`MEMORY_BASE + i_length[1:0]), 0, i_length, tmp); |
end |
else |
begin |
check_tx_packet(((`MEMORY_BASE + i_length[1:0]) + max_tmp), max_tmp, i_length, tmp); |
end |
if (tmp > 0) |
begin |
test_fail("Wrong data of the transmitted packet"); |
fail = fail + 1; |
end |
// check transmited TX packet CRC |
if (i_length[0] == 0) |
check_tx_crc(0, i_length, 1'b0, tmp); // length without CRC |
else |
check_tx_crc(max_tmp, i_length, 1'b0, tmp); // length without CRC |
if (tmp > 0) |
begin |
test_fail("Wrong CRC of the transmitted packet"); |
fail = fail + 1; |
end |
// check WB INT signal |
if (i_length[1:0] == 2'h0) |
begin |
if (wb_int !== 1'b1) |
begin |
`TIME; $display("*E WB INT signal should be set"); |
test_fail("WB INT signal should be set"); |
fail = fail + 1; |
end |
end |
else |
begin |
if (wb_int !== 1'b0) |
begin |
`TIME; $display("*E WB INT signal should not be set"); |
test_fail("WB INT signal should not be set"); |
fail = fail + 1; |
end |
end |
// check TX buffer descriptor of a packet |
check_tx_bd(num_of_bd, data); |
if (i_length[1] == 1'b0) // interrupt enabled |
begin |
if ( ((data[15:0] !== 16'h7800) && ((num_of_frames < 8) || ((num_of_frames - 8) == 127))) || // wrap bit |
((data[15:0] !== 16'h5800) && (num_of_frames >= 8) && ((num_of_frames - 8) != 127)) ) // without wrap bit |
begin |
`TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]); |
test_fail("TX buffer descriptor status is not correct"); |
fail = fail + 1; |
end |
end |
else // interrupt not enabled |
begin |
if ( ((data[15:0] !== 16'h3800) && ((num_of_frames < 8) || ((num_of_frames - 8) == 127))) || // wrap bit |
((data[15:0] !== 16'h1800) && (num_of_frames >= 8) && ((num_of_frames - 8) != 127)) ) // without wrap bit |
begin |
`TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]); |
test_fail("TX buffer descriptor status is not correct"); |
fail = fail + 1; |
end |
end |
// clear first half of 8 frames from TX buffer descriptor 0 |
if (num_of_frames < 4) |
clear_tx_bd(num_of_bd, num_of_bd); |
// clear BD with wrap bit |
if (num_of_frames == 140) |
clear_tx_bd(127, 127); |
// check interrupts |
wait (wbm_working == 0); |
wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if ((i_length[1:0] == 2'h0) || (i_length[1:0] == 2'h1)) |
begin |
if ((data & `ETH_INT_TXB) !== 1'b1) |
begin |
`TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data); |
test_fail("Interrupt Transmit Buffer was not set"); |
fail = fail + 1; |
end |
if ((data & (~`ETH_INT_TXB)) !== 0) |
begin |
`TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data); |
test_fail("Other interrupts (except Transmit Buffer) were set"); |
fail = fail + 1; |
end |
end |
else |
begin |
if (data !== 0) |
begin |
`TIME; $display("*E Any of interrupts (except Transmit Buffer) was set, interrupt reg: %0h, len: %0h", data, i_length[1:0]); |
test_fail("Any of interrupts (except Transmit Buffer) was set"); |
fail = fail + 1; |
end |
end |
// clear interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// check WB INT signal |
if (wb_int !== 1'b0) |
begin |
test_fail("WB INT signal should not be set"); |
fail = fail + 1; |
end |
// INTERMEDIATE DISPLAYS |
if ((i_length + 4) == (min_tmp + 7)) |
begin |
// starting length is min_tmp, ending length is (min_tmp + 128) |
$display(" pads appending to packets is NOT selected"); |
$display(" using only TX BD 0 out of 128 BDs assigned to TX (wrap at first BD - TX BD 0)"); |
$display(" ->packets with lengths from %0d (MINFL) to %0d are checked (length increasing by 1 byte)", |
min_tmp, (min_tmp + 7)); |
$display(" ->all packets were send from TX BD 0"); |
// set padding, remain the rest |
wait (wbm_working == 0); |
wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN, |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
end |
else if ((i_length + 4) == (min_tmp + 128)) |
begin |
// starting length is min_tmp, ending length is (min_tmp + 128) |
$display(" pads appending to packets is NOT selected"); |
$display(" using all 128 BDs assigned to TX (wrap at 128th BD - TX BD 127)"); |
$display(" ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)", |
(min_tmp + 8), (min_tmp + 128)); |
$display(" ->packets were send from TX BD %0d to TX BD %0d respectively", |
1'b0, num_of_bd); |
tmp_bd = num_of_bd + 1; |
// set padding, remain the rest |
wait (wbm_working == 0); |
wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN, |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
end |
else if ((i_length + 4) == (max_tmp - 16)) |
begin |
// starting length is for +128 longer than previous ending length, while ending length is tmp_data |
$display(" pads appending to packets is selected"); |
$display(" using all 128 BDs assigned to TX (wrap at 128th BD - TX BD 127)"); |
$display(" ->packets with lengths from %0d to %0d are checked (length increasing by 128 bytes)", |
(min_tmp + 64 + 128), tmp_data); |
if (tmp_bd > num_of_bd) |
$display(" ->packets were send from TX BD %0d to TX BD 127 and from TX BD 0 to TX BD %0d respectively", |
tmp_bd, num_of_bd); |
else |
$display(" ->packets were send from TX BD %0d to TX BD %0d respectively", |
tmp_bd, num_of_bd); |
tmp_bd = num_of_bd + 1; |
// reset padding, remain the rest |
wait (wbm_working == 0); |
wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN, |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
end |
else if ((i_length + 4) == max_tmp) |
begin |
$display(" pads appending to packets is NOT selected"); |
$display(" using all 128 BDs assigned to TX (wrap at 128th BD - TX BD 127)"); |
$display(" ->packets with lengths from %0d to %0d (MAXFL) are checked (length increasing by 1 byte)", |
(max_tmp - (4 + 16)), max_tmp); |
if (tmp_bd > num_of_bd) |
$display(" ->packets were send from TX BD %0d to TX BD 127 and from TX BD 0 to TX BD %0d respectively", |
tmp_bd, num_of_bd); |
else |
$display(" ->packets were send from TX BD %0d to TX BD %0d respectively", |
tmp_bd, num_of_bd); |
end |
// set length (loop variable) |
if ((i_length + 4) < (min_tmp + 128)) |
i_length = i_length + 1; |
else if ( ((i_length + 4) == (min_tmp + 128)) && ((i_length + 4) <= (max_tmp - 256)) ) |
i_length = 256; |
else if ( ((i_length + 4) > (min_tmp + 128)) && ((i_length + 4) <= (max_tmp - 256)) ) |
begin |
i_length = i_length + 128; |
tmp_data = i_length + 4; // last tmp_data is ending length |
end |
else if ( ((i_length + 4) > (max_tmp - 256)) && ((i_length + 4) < (max_tmp - 16)) ) |
i_length = max_tmp - (4 + 16); |
else if ((i_length + 4) >= (max_tmp - 16)) |
i_length = i_length + 1; |
else |
begin |
$display("*E TESTBENCH ERROR - WRONG PARAMETERS IN TESTBENCH"); |
#10 $stop; |
end |
// the number of frame transmitted |
num_of_frames = num_of_frames + 1; |
if ((num_of_frames <= 8) || ((num_of_frames - 8) == 128)) |
num_of_bd = 0; |
else |
num_of_bd = num_of_bd + 1; |
end |
// disable TX |
wait (wbm_working == 0); |
wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN, |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
@(posedge wb_clk); |
if(fail == 0) |
test_ok; |
else |
fail = 0; |
end |
|
|
//////////////////////////////////////////////////////////////////// |
//// //// |
//// Test transmit packets form MINFL to MAXFL sizes at //// |
//// maximum TX buffer decriptors ( 100Mbps ). //// |
//// //// |
//////////////////////////////////////////////////////////////////// |
if (test_num == 5) // with and without padding |
begin |
// TEST 5: TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT MAX TX BDs ( 100Mbps ) |
test_name = "TEST 5: TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT MAX TX BDs ( 100Mbps )"; |
`TIME; $display(" TEST 5: TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT MAX TX BDs ( 100Mbps )"); |
|
// reset MAC registers |
hard_reset; |
// reset MAC and MII LOGIC with soft reset |
// reset_mac; |
// reset_mii; |
// set wb slave response |
wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries); |
|
max_tmp = 0; |
min_tmp = 0; |
num_of_frames = 0; |
num_of_bd = 0; |
// set maximum TX buffer descriptors (128) - must be set before TX enable |
wait (wbm_working == 0); |
wbm_write(`ETH_TX_BD_NUM, 32'h80, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// enable TX, set full-duplex mode, NO padding and CRC appending |
wait (wbm_working == 0); |
wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN, |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// prepare two packets of MAXFL length |
wait (wbm_working == 0); |
wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC |
min_tmp = tmp[31:16]; |
st_data = 8'hA5; |
set_tx_packet(`MEMORY_BASE, (max_tmp), st_data); // length without CRC |
st_data = 8'h71; |
set_tx_packet((`MEMORY_BASE + max_tmp), (max_tmp), st_data); // length without CRC |
// check WB INT signal |
if (wb_int !== 1'b0) |
begin |
test_fail("WB INT signal should not be set"); |
fail = fail + 1; |
end |
|
// write to phy's control register for 100Mbps |
#Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 set - speed 100 |
#Tp eth_phy.control_bit8_0 = 9'h1_00; // bit 6 reset - (10/100), bit 8 set - FD |
speed = 100; |
|
i_length = (min_tmp - 4); |
while (i_length <= (max_tmp - 4)) |
begin |
// choose generating carrier sense and collision |
case (i_length[1:0]) |
2'h0: // Interrupt is generated |
begin |
// Reset_tx_bd nable interrupt generation |
// unmask interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY | |
`ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// not detect carrier sense in FD and no collision |
eth_phy.carrier_sense_tx_fd_detect(0); |
eth_phy.collision(0); |
end |
2'h1: // Interrupt is not generated |
begin |
// set_tx_bd enable interrupt generation |
// mask interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// detect carrier sense in FD and no collision |
eth_phy.carrier_sense_tx_fd_detect(1); |
eth_phy.collision(0); |
end |
2'h2: // Interrupt is not generated |
begin |
// set_tx_bd disable the interrupt generation |
// unmask interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY | |
`ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// not detect carrier sense in FD and set collision |
eth_phy.carrier_sense_tx_fd_detect(0); |
eth_phy.collision(1); |
end |
default: // 2'h3: // Interrupt is not generated |
begin |
// set_tx_bd disable the interrupt generation |
// mask interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// detect carrier sense in FD and set collision |
eth_phy.carrier_sense_tx_fd_detect(1); |
eth_phy.collision(1); |
end |
endcase |
// first destination address on ethernet PHY |
if (i_length[0] == 0) |
eth_phy.set_tx_mem_addr(0); |
else |
eth_phy.set_tx_mem_addr(max_tmp); |
// first 8 frames are transmitted with TX BD 0 (wrap bit on TX BD 0) |
// number of all frames is 154 (146 without first 8) |
if (num_of_frames < 8) |
begin |
case (i_length[1:0]) |
2'h0: // Interrupt is generated |
begin |
// enable interrupt generation |
set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, (`MEMORY_BASE + i_length[1:0])); |
// interrupts are unmasked |
end |
2'h1: // Interrupt is not generated |
begin |
// enable interrupt generation |
set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, ((`MEMORY_BASE + i_length[1:0]) + max_tmp)); |
// interrupts are masked |
end |
2'h2: // Interrupt is not generated |
begin |
// disable interrupt generation |
set_tx_bd(0, 0, i_length, 1'b0, 1'b1, 1'b1, (`MEMORY_BASE + i_length[1:0])); |
// interrupts are unmasked |
end |
default: // 2'h3: // Interrupt is not generated |
begin |
// disable interrupt generation |
set_tx_bd(0, 0, i_length, 1'b0, 1'b1, 1'b1, ((`MEMORY_BASE + i_length[1:0]) + max_tmp)); |
// interrupts are masked |
end |
endcase |
// set wrap bit |
set_tx_bd_wrap(0); |
end |
// after first 8 number of frames, 128 frames form TX BD 0 to 127 will be transmitted |
else if ((num_of_frames - 8) == 0) |
begin |
tmp_len = i_length; // length of frame |
tmp_bd_num = 0; // TX BD number |
while (tmp_bd_num < 128) // (tmp_len <= (max_tmp - 4)) - this is the last frame |
begin |
// if i_length[1] == 0 then enable interrupt generation otherwise disable it |
// if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp |
if (tmp_len[0] == 0) |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + tmp_len[1:0])); |
else |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, ((`MEMORY_BASE + tmp_len[1:0]) + max_tmp)); |
// set length (loop variable) - THE SAME AS AT THE END OF THIS TASK !!! |
if ((tmp_len + 4) < (min_tmp + 128)) |
tmp_len = tmp_len + 1; |
else if ( ((tmp_len + 4) == (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) ) |
tmp_len = 256; |
else if ( ((tmp_len + 4) > (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) ) |
tmp_len = tmp_len + 128; |
else if ( ((tmp_len + 4) > (max_tmp - 256)) && ((tmp_len + 4) < (max_tmp - 16)) ) |
tmp_len = max_tmp - (4 + 16); |
else if ((tmp_len + 4) >= (max_tmp - 16)) |
tmp_len = tmp_len + 1; |
// set TX BD number |
tmp_bd_num = tmp_bd_num + 1; |
end |
// set wrap bit |
set_tx_bd_wrap(127); |
end |
// after 128 + first 8 number of frames, 19 frames form TX BD 0 to 18 will be transmitted |
else if ((num_of_frames - 8) == 20) // 128 |
begin |
tmp_len = tmp_len; // length of frame remaines from previous settings |
tmp_bd_num = 0; // TX BD number |
while (tmp_bd_num < 19) // (tmp_len <= (max_tmp - 4)) - this is the last frame |
begin |
// if i_length[1] == 0 then enable interrupt generation otherwise disable it |
// if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp |
if (tmp_len[0] == 0) |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + tmp_len[1:0])); |
else |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, ((`MEMORY_BASE + tmp_len[1:0]) + max_tmp)); |
// set length (loop variable) - THE SAME AS AT THE END OF THIS TASK !!! |
if ((tmp_len + 4) < (min_tmp + 128)) |
tmp_len = tmp_len + 1; |
else if ( ((tmp_len + 4) == (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) ) |
tmp_len = 256; |
else if ( ((tmp_len + 4) > (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) ) |
tmp_len = tmp_len + 128; |
else if ( ((tmp_len + 4) > (max_tmp - 256)) && ((tmp_len + 4) < (max_tmp - 16)) ) |
tmp_len = max_tmp - (4 + 16); |
else if ((tmp_len + 4) >= (max_tmp - 16)) |
tmp_len = tmp_len + 1; |
// set TX BD number |
tmp_bd_num = tmp_bd_num + 1; |
end |
end |
// set ready bit |
if (num_of_frames < 8) |
set_tx_bd_ready(0, 0); |
else if ((num_of_frames - 8) < 128) |
set_tx_bd_ready((num_of_frames - 8), (num_of_frames - 8)); |
else if ((num_of_frames - 136) < 19) |
set_tx_bd_ready((num_of_frames - 136), (num_of_frames - 136)); |
// CHECK END OF TRANSMITION |
#1 check_tx_bd(num_of_bd, data); |
if (i_length < min_tmp) // just first four |
begin |
while (data[15] === 1) |
begin |
#1 check_tx_bd(num_of_bd, data); |
@(posedge wb_clk); |
end |
repeat (1) @(posedge wb_clk); |
end |
else if (i_length > (max_tmp - 8)) // just last four |
begin |
tmp = 0; |
wait (MTxEn === 1'b1); // start transmit |
while (tmp < (i_length - 20)) |
begin |
#1 tmp = tmp + 1; |
@(posedge wb_clk); |
end |
#1 check_tx_bd(num_of_bd, data); |
while (data[15] === 1) |
begin |
#1 check_tx_bd(num_of_bd, data); |
@(posedge wb_clk); |
end |
repeat (1) @(posedge wb_clk); |
end |
else |
begin |
wait (MTxEn === 1'b1); // start transmit |
#1 check_tx_bd(num_of_bd, data); |
if (data[15] !== 1) |
begin |
test_fail("Wrong buffer descriptor's ready bit read out from MAC"); |
fail = fail + 1; |
end |
wait (MTxEn === 1'b0); // end transmit |
while (data[15] === 1) |
begin |
#1 check_tx_bd(num_of_bd, data); |
@(posedge wb_clk); |
end |
repeat (1) @(posedge wb_clk); |
end |
// check length of a PACKET |
if (eth_phy.tx_len != (i_length + 4)) |
begin |
test_fail("Wrong length of the packet out from MAC"); |
fail = fail + 1; |
end |
// checking in the following if statement is performed only for first and last 64 lengths |
// check transmitted TX packet data |
if (i_length[0] == 0) |
begin |
check_tx_packet((`MEMORY_BASE + i_length[1:0]), 0, i_length, tmp); |
end |
else |
begin |
check_tx_packet(((`MEMORY_BASE + i_length[1:0]) + max_tmp), max_tmp, i_length, tmp); |
end |
if (tmp > 0) |
begin |
test_fail("Wrong data of the transmitted packet"); |
fail = fail + 1; |
end |
// check transmited TX packet CRC |
if (i_length[0] == 0) |
check_tx_crc(0, i_length, 1'b0, tmp); // length without CRC |
else |
check_tx_crc(max_tmp, i_length, 1'b0, tmp); // length without CRC |
if (tmp > 0) |
begin |
test_fail("Wrong CRC of the transmitted packet"); |
fail = fail + 1; |
end |
// check WB INT signal |
if (i_length[1:0] == 2'h0) |
begin |
if (wb_int !== 1'b1) |
begin |
`TIME; $display("*E WB INT signal should be set"); |
test_fail("WB INT signal should be set"); |
fail = fail + 1; |
end |
end |
else |
begin |
if (wb_int !== 1'b0) |
begin |
`TIME; $display("*E WB INT signal should not be set"); |
test_fail("WB INT signal should not be set"); |
fail = fail + 1; |
end |
end |
// check TX buffer descriptor of a packet |
check_tx_bd(num_of_bd, data); |
if (i_length[1] == 1'b0) // interrupt enabled |
begin |
if ( ((data[15:0] !== 16'h7800) && ((num_of_frames < 8) || ((num_of_frames - 8) == 127))) || // wrap bit |
((data[15:0] !== 16'h5800) && (num_of_frames >= 8) && ((num_of_frames - 8) != 127)) ) // without wrap bit |
begin |
`TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]); |
test_fail("TX buffer descriptor status is not correct"); |
fail = fail + 1; |
end |
end |
else // interrupt not enabled |
begin |
if ( ((data[15:0] !== 16'h3800) && ((num_of_frames < 8) || ((num_of_frames - 8) == 127))) || // wrap bit |
((data[15:0] !== 16'h1800) && (num_of_frames >= 8) && ((num_of_frames - 8) != 127)) ) // without wrap bit |
begin |
`TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]); |
test_fail("TX buffer descriptor status is not correct"); |
fail = fail + 1; |
end |
end |
// clear first half of 8 frames from TX buffer descriptor 0 |
if (num_of_frames < 4) |
clear_tx_bd(num_of_bd, num_of_bd); |
// clear BD with wrap bit |
if (num_of_frames == 140) |
clear_tx_bd(127, 127); |
// check interrupts |
wait (wbm_working == 0); |
wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if ((i_length[1:0] == 2'h0) || (i_length[1:0] == 2'h1)) |
begin |
if ((data & `ETH_INT_TXB) !== 1'b1) |
begin |
`TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data); |
test_fail("Interrupt Transmit Buffer was not set"); |
fail = fail + 1; |
end |
if ((data & (~`ETH_INT_TXB)) !== 0) |
begin |
`TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data); |
test_fail("Other interrupts (except Transmit Buffer) were set"); |
fail = fail + 1; |
end |
end |
else |
begin |
if (data !== 0) |
begin |
`TIME; $display("*E Any of interrupts (except Transmit Buffer) was set, interrupt reg: %0h, len: %0h", data, i_length[1:0]); |
test_fail("Any of interrupts (except Transmit Buffer) was set"); |
fail = fail + 1; |
end |
end |
// clear interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// check WB INT signal |
if (wb_int !== 1'b0) |
begin |
test_fail("WB INT signal should not be set"); |
fail = fail + 1; |
end |
// INTERMEDIATE DISPLAYS |
if ((i_length + 4) == (min_tmp + 7)) |
begin |
// starting length is min_tmp, ending length is (min_tmp + 128) |
$display(" pads appending to packets is NOT selected"); |
$display(" using only TX BD 0 out of 128 BDs assigned to TX (wrap at first BD - TX BD 0)"); |
$display(" ->packets with lengths from %0d (MINFL) to %0d are checked (length increasing by 1 byte)", |
min_tmp, (min_tmp + 7)); |
$display(" ->all packets were send from TX BD 0"); |
// set padding, remain the rest |
wait (wbm_working == 0); |
wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN, |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
end |
else if ((i_length + 4) == (min_tmp + 128)) |
begin |
// starting length is min_tmp, ending length is (min_tmp + 128) |
$display(" pads appending to packets is NOT selected"); |
$display(" using all 128 BDs assigned to TX (wrap at 128th BD - TX BD 127)"); |
$display(" ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)", |
(min_tmp + 8), (min_tmp + 128)); |
$display(" ->packets were send from TX BD %0d to TX BD %0d respectively", |
1'b0, num_of_bd); |
tmp_bd = num_of_bd + 1; |
// set padding, remain the rest |
wait (wbm_working == 0); |
wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN, |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
end |
else if ((i_length + 4) == (max_tmp - 16)) |
begin |
// starting length is for +128 longer than previous ending length, while ending length is tmp_data |
$display(" pads appending to packets is selected"); |
$display(" using all 128 BDs assigned to TX (wrap at 128th BD - TX BD 127)"); |
$display(" ->packets with lengths from %0d to %0d are checked (length increasing by 128 bytes)", |
(min_tmp + 64 + 128), tmp_data); |
if (tmp_bd > num_of_bd) |
$display(" ->packets were send from TX BD %0d to TX BD 127 and from TX BD 0 to TX BD %0d respectively", |
tmp_bd, num_of_bd); |
else |
$display(" ->packets were send from TX BD %0d to TX BD %0d respectively", |
tmp_bd, num_of_bd); |
tmp_bd = num_of_bd + 1; |
// reset padding, remain the rest |
wait (wbm_working == 0); |
wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN, |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
end |
else if ((i_length + 4) == max_tmp) |
begin |
$display(" pads appending to packets is NOT selected"); |
$display(" using all 128 BDs assigned to TX (wrap at 128th BD - TX BD 127)"); |
$display(" ->packets with lengths from %0d to %0d (MAXFL) are checked (length increasing by 1 byte)", |
(max_tmp - (4 + 16)), max_tmp); |
if (tmp_bd > num_of_bd) |
$display(" ->packets were send from TX BD %0d to TX BD 127 and from TX BD 0 to TX BD %0d respectively", |
tmp_bd, num_of_bd); |
else |
$display(" ->packets were send from TX BD %0d to TX BD %0d respectively", |
tmp_bd, num_of_bd); |
end |
// set length (loop variable) |
if ((i_length + 4) < (min_tmp + 128)) |
i_length = i_length + 1; |
else if ( ((i_length + 4) == (min_tmp + 128)) && ((i_length + 4) <= (max_tmp - 256)) ) |
i_length = 256; |
else if ( ((i_length + 4) > (min_tmp + 128)) && ((i_length + 4) <= (max_tmp - 256)) ) |
begin |
i_length = i_length + 128; |
tmp_data = i_length + 4; // last tmp_data is ending length |
end |
else if ( ((i_length + 4) > (max_tmp - 256)) && ((i_length + 4) < (max_tmp - 16)) ) |
i_length = max_tmp - (4 + 16); |
else if ((i_length + 4) >= (max_tmp - 16)) |
i_length = i_length + 1; |
else |
begin |
$display("*E TESTBENCH ERROR - WRONG PARAMETERS IN TESTBENCH"); |
#10 $stop; |
end |
// the number of frame transmitted |
num_of_frames = num_of_frames + 1; |
if ((num_of_frames <= 8) || ((num_of_frames - 8) == 128)) |
num_of_bd = 0; |
else |
num_of_bd = num_of_bd + 1; |
end |
// disable TX |
wait (wbm_working == 0); |
wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN, |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
@(posedge wb_clk); |
if(fail == 0) |
test_ok; |
else |
fail = 0; |
end |
|
|
//////////////////////////////////////////////////////////////////// |
//// //// |
//// Test transmit packets form 0 to (MINFL - 1) sizes at //// |
//// 8 TX buffer decriptors ( 10Mbps ). //// |
//// //// |
//////////////////////////////////////////////////////////////////// |
if (test_num == 6) // |
begin |
// TEST 6: TRANSMIT PACKETS FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 10Mbps ) |
test_name = "TEST 6: TRANSMIT PACKETS FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 10Mbps )"; |
`TIME; $display(" TEST 6: TRANSMIT PACKETS FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 10Mbps )"); |
|
// reset MAC registers |
hard_reset; |
// reset MAC and MII LOGIC with soft reset |
// reset_mac; |
// reset_mii; |
// set wb slave response |
wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries); |
|
max_tmp = 0; |
min_tmp = 0; |
// set 8 TX buffer descriptors - must be set before TX enable |
wait (wbm_working == 0); |
wbm_write(`ETH_TX_BD_NUM, 32'h8, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// enable TX, set full-duplex mode, padding and CRC appending |
wait (wbm_working == 0); |
wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_PAD | `ETH_MODER_FULLD | `ETH_MODER_CRCEN, |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// prepare two packets of MAXFL length |
wait (wbm_working == 0); |
wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC |
min_tmp = tmp[31:16]; |
st_data = 8'h12; |
set_tx_packet(`MEMORY_BASE, (max_tmp - 4), st_data); // length without CRC |
st_data = 8'h34; |
set_tx_packet((`MEMORY_BASE + max_tmp), (max_tmp - 4), st_data); // length without CRC |
// check WB INT signal |
if (wb_int !== 1'b0) |
begin |
test_fail("WB INT signal should not be set"); |
fail = fail + 1; |
end |
|
// write to phy's control register for 10Mbps |
#Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10 |
#Tp eth_phy.control_bit8_0 = 9'h1_00; // bit 6 reset - (10/100), bit 8 set - FD |
speed = 10; |
|
frame_started = 0; |
num_of_frames = 0; |
num_of_bd = 0; |
i_length = 0; // 0; |
while (i_length < 70) // (min_tmp - 4)) |
begin |
#1; |
// choose generating carrier sense and collision |
case (i_length[1:0]) |
2'h0: // Interrupt is generated |
begin |
// Reset_tx_bd nable interrupt generation |
// unmask interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY | |
`ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// not detect carrier sense in FD and no collision |
eth_phy.carrier_sense_tx_fd_detect(0); |
eth_phy.collision(0); |
end |
2'h1: // Interrupt is not generated |
begin |
// set_tx_bd enable interrupt generation |
// mask interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// detect carrier sense in FD and no collision |
eth_phy.carrier_sense_tx_fd_detect(1); |
eth_phy.collision(0); |
end |
2'h2: // Interrupt is not generated |
begin |
// set_tx_bd disable the interrupt generation |
// unmask interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY | |
`ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// not detect carrier sense in FD and set collision |
eth_phy.carrier_sense_tx_fd_detect(0); |
eth_phy.collision(1); |
end |
default: // 2'h3: // Interrupt is not generated |
begin |
// set_tx_bd disable the interrupt generation |
// mask interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// detect carrier sense in FD and set collision |
eth_phy.carrier_sense_tx_fd_detect(1); |
eth_phy.collision(1); |
end |
endcase |
#1; |
// first destination address on ethernet PHY |
eth_phy.set_tx_mem_addr(num_of_frames * 16); |
// SET packets and wrap bit |
// num_of_frames <= 9 => wrap set to TX BD 0 |
if (num_of_frames <= 9) |
begin |
tmp_len = i_length; // length of frame |
tmp_bd_num = 0; // TX BD number |
// if i_length[1] == 0 then enable interrupt generation otherwise disable it |
// if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp |
if (tmp_len[0] == 0) |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE); |
else |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp)); |
// set wrap bit |
set_tx_bd_wrap(0); |
end |
// 10 <= num_of_frames < 18 => wrap set to TX BD 3 |
else if ((num_of_frames == 10) || (num_of_frames == 14)) |
begin |
tmp_len = i_length; // length of frame |
tmp_bd_num = 0; // TX BD number |
while (tmp_bd_num < 4) // |
begin |
// if i_length[1] == 0 then enable interrupt generation otherwise disable it |
// if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp |
if (tmp_len[0] == 0) |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE); |
else |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp)); |
tmp_len = tmp_len + 1; |
// set TX BD number |
tmp_bd_num = tmp_bd_num + 1; |
end |
// set wrap bit |
set_tx_bd_wrap(3); |
end |
// 18 <= num_of_frames < 28 => wrap set to TX BD 4 |
else if ((num_of_frames == 18) || (num_of_frames == 23)) |
begin |
tmp_len = i_length; // length of frame |
tmp_bd_num = 0; // TX BD number |
while (tmp_bd_num < 5) // |
begin |
// if i_length[1] == 0 then enable interrupt generation otherwise disable it |
// if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp |
if (tmp_len[0] == 0) |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE); |
else |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp)); |
tmp_len = tmp_len + 1; |
// set TX BD number |
tmp_bd_num = tmp_bd_num + 1; |
end |
// set wrap bit |
set_tx_bd_wrap(4); |
end |
// 28 <= num_of_frames < 40 => wrap set to TX BD 5 |
else if ((num_of_frames == 28) || (num_of_frames == 34)) |
begin |
tmp_len = i_length; // length of frame |
tmp_bd_num = 0; // TX BD number |
while (tmp_bd_num < 6) // |
begin |
// if i_length[1] == 0 then enable interrupt generation otherwise disable it |
// if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp |
if (tmp_len[0] == 0) |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE); |
else |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp)); |
tmp_len = tmp_len + 1; |
// set TX BD number |
tmp_bd_num = tmp_bd_num + 1; |
end |
// set wrap bit |
set_tx_bd_wrap(5); |
end |
// 40 <= num_of_frames < 54 => wrap set to TX BD 6 |
else if ((num_of_frames == 40) || (num_of_frames == 47)) |
begin |
tmp_len = i_length; // length of frame |
tmp_bd_num = 0; // TX BD number |
while (tmp_bd_num < 7) // |
begin |
// if i_length[1] == 0 then enable interrupt generation otherwise disable it |
// if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp |
if (tmp_len[0] == 0) |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE); |
else |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp)); |
tmp_len = tmp_len + 1; |
// set TX BD number |
tmp_bd_num = tmp_bd_num + 1; |
end |
// set wrap bit |
set_tx_bd_wrap(6); |
end |
// 54 <= num_of_frames < 70 => wrap set to TX BD 7 |
else if ((num_of_frames == 54) || (num_of_frames == 62)) |
begin |
tmp_len = i_length; // length of frame |
tmp_bd_num = 0; // TX BD number |
while (tmp_bd_num < 8) // |
begin |
// if i_length[1] == 0 then enable interrupt generation otherwise disable it |
// if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp |
if (tmp_len[0] == 0) |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE); |
else |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp)); |
tmp_len = tmp_len + 1; |
// set TX BD number |
tmp_bd_num = tmp_bd_num + 1; |
end |
// set wrap bit |
set_tx_bd_wrap(7); |
end |
#1; |
// SET ready bit |
if (num_of_frames < 10) |
set_tx_bd_ready(0, 0); |
else if (num_of_frames < 14) |
set_tx_bd_ready((num_of_frames - 10), (num_of_frames - 10)); |
else if (num_of_frames < 18) |
set_tx_bd_ready((num_of_frames - 14), (num_of_frames - 14)); |
else if (num_of_frames < 23) |
set_tx_bd_ready((num_of_frames - 18), (num_of_frames - 18)); |
else if (num_of_frames < 28) |
set_tx_bd_ready((num_of_frames - 23), (num_of_frames - 23)); |
else if (num_of_frames < 34) |
set_tx_bd_ready((num_of_frames - 28), (num_of_frames - 28)); |
else if (num_of_frames < 40) |
set_tx_bd_ready((num_of_frames - 34), (num_of_frames - 34)); |
else if (num_of_frames < 47) |
set_tx_bd_ready((num_of_frames - 40), (num_of_frames - 40)); |
else if (num_of_frames < 54) |
set_tx_bd_ready((num_of_frames - 47), (num_of_frames - 47)); |
else if (num_of_frames < 62) |
set_tx_bd_ready((num_of_frames - 54), (num_of_frames - 54)); |
else if (num_of_frames < 70) |
set_tx_bd_ready((num_of_frames - 62), (num_of_frames - 62)); |
// CHECK END OF TRANSMITION |
frame_started = 0; |
if (num_of_frames >= 5) |
#1 check_tx_bd(num_of_bd, data); |
fork |
begin: fr_st |
wait (MTxEn === 1'b1); // start transmit |
frame_started = 1; |
end |
begin |
repeat (30) @(posedge mtx_clk); |
if (num_of_frames < 5) |
begin |
if (frame_started == 1) |
begin |
`TIME; $display("*E Frame should NOT start!"); |
end |
disable fr_st; |
end |
else |
begin |
if (frame_started == 0) |
begin |
`TIME; $display("*W Frame should start!"); |
disable fr_st; |
end |
end |
end |
join |
// check packets larger than 4 bytes |
if (num_of_frames >= 5) |
begin |
wait (MTxEn === 1'b0); // end transmit |
while (data[15] === 1) |
begin |
#1 check_tx_bd(num_of_bd, data); |
@(posedge wb_clk); |
end |
repeat (1) @(posedge wb_clk); |
// check length of a PACKET |
if (i_length <= (min_tmp - 4)) |
begin |
if (eth_phy.tx_len != min_tmp) |
begin |
test_fail("Wrong length of the packet out from MAC"); |
fail = fail + 1; |
end |
end |
else |
begin |
if (eth_phy.tx_len != (i_length + 4)) |
begin |
test_fail("Wrong length of the packet out from MAC"); |
fail = fail + 1; |
end |
end |
// check transmitted TX packet data |
if (i_length[0] == 0) |
begin |
#1 check_tx_packet(`MEMORY_BASE, (num_of_frames * 16), i_length, tmp); |
end |
else |
begin |
#1 check_tx_packet((`MEMORY_BASE + max_tmp), (num_of_frames * 16), i_length, tmp); |
end |
if (tmp > 0) |
begin |
test_fail("Wrong data of the transmitted packet"); |
fail = fail + 1; |
end |
// check transmited TX packet CRC |
if (num_of_frames < (min_tmp - 4)) |
#1 check_tx_crc((num_of_frames * 16), (min_tmp - 4), 1'b0, tmp); // length without CRC |
else |
#1 check_tx_crc((num_of_frames * 16), i_length, 1'b0, tmp); // length without CRC |
if (tmp > 0) |
begin |
test_fail("Wrong CRC of the transmitted packet"); |
fail = fail + 1; |
end |
end |
// check WB INT signal |
if ((i_length[1:0] == 2'h0) && (num_of_frames >= 5)) |
begin |
if (wb_int !== 1'b1) |
begin |
`TIME; $display("*E WB INT signal should be set"); |
test_fail("WB INT signal should be set"); |
fail = fail + 1; |
end |
end |
else |
begin |
if (wb_int !== 1'b0) |
begin |
`TIME; $display("*E WB INT signal should not be set"); |
test_fail("WB INT signal should not be set"); |
fail = fail + 1; |
end |
end |
// check TX buffer descriptor of a packet |
check_tx_bd(num_of_bd, data); |
if (num_of_frames >= 5) |
begin |
if (i_length[1] == 1'b0) // interrupt enabled |
begin |
if ( (data[15:0] !== 16'h7800) && // wrap bit |
(data[15:0] !== 16'h5800) ) // without wrap bit |
begin |
`TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]); |
test_fail("TX buffer descriptor status is not correct"); |
fail = fail + 1; |
end |
end |
else // interrupt not enabled |
begin |
if ( (data[15:0] !== 16'h3800) && // wrap bit |
(data[15:0] !== 16'h1800) ) // without wrap bit |
begin |
`TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]); |
test_fail("TX buffer descriptor status is not correct"); |
fail = fail + 1; |
end |
end |
end |
else |
begin |
if (data[15] !== 1'b1) |
begin |
`TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]); |
test_fail("TX buffer descriptor status is not correct"); |
fail = fail + 1; |
end |
end |
// clear TX BD with wrap bit |
if (num_of_frames == 63) |
clear_tx_bd(16, 16); |
// check interrupts |
wait (wbm_working == 0); |
wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if ( ((i_length[1:0] == 2'h0) || (i_length[1:0] == 2'h1)) && (num_of_frames >= 5) ) |
begin |
if ((data & `ETH_INT_TXB) !== 1'b1) |
begin |
`TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data); |
test_fail("Interrupt Transmit Buffer was not set"); |
fail = fail + 1; |
end |
if ((data & (~`ETH_INT_TXB)) !== 0) |
begin |
`TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data); |
test_fail("Other interrupts (except Transmit Buffer) were set"); |
fail = fail + 1; |
end |
end |
else |
begin |
if (data !== 0) |
begin |
`TIME; $display("*E Any of interrupts (except Transmit Buffer) was set, interrupt reg: %0h, len: %0h", data, i_length[1:0]); |
test_fail("Any of interrupts (except Transmit Buffer) was set"); |
fail = fail + 1; |
end |
end |
// clear interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// check WB INT signal |
if (wb_int !== 1'b0) |
begin |
test_fail("WB INT signal should not be set"); |
fail = fail + 1; |
end |
// INTERMEDIATE DISPLAYS |
if (i_length == 3) |
begin |
$display(" pads appending to packets is selected"); |
$display(" using 1 BD out of 8 BDs assigned to TX (wrap at 1st BD - TX BD 0)"); |
$display(" ->packets with lengths from %0d to %0d are not transmitted (length increasing by 1 byte)", |
0, 3); |
end |
else if (i_length == 9) |
begin |
$display(" using 1 BD out of 8 BDs assigned to TX (wrap at 1st BD - TX BD 0)"); |
$display(" ->packet with length 4 is not transmitted (length increasing by 1 byte)"); |
$display(" ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)", |
5, 9); |
end |
else if (i_length == 17) |
begin |
$display(" using 4 BDs out of 8 BDs assigned to TX (wrap at 4th BD - TX BD 3)"); |
$display(" ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)", |
10, 17); |
end |
else if (i_length == 27) |
begin |
$display(" using 5 BDs out of 8 BDs assigned to TX (wrap at 5th BD - TX BD 4)"); |
$display(" ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)", |
18, 27); |
end |
else if (i_length == 40) |
begin |
$display(" using 6 BDs out of 8 BDs assigned to TX (wrap at 6th BD - TX BD 5)"); |
$display(" ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)", |
28, 40); |
end |
else if (i_length == 54) |
begin |
$display(" using 7 BDs out of 8 BDs assigned to TX (wrap at 7th BD - TX BD 6)"); |
$display(" ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)", |
41, 54); |
end |
else if (i_length == 69) |
begin |
$display(" using 8 BDs out of 8 BDs assigned to TX (wrap at 8th BD - TX BD 7)"); |
$display(" ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)", |
55, 69); |
end |
// set length (loop variable) |
i_length = i_length + 1; |
// the number of frame transmitted |
num_of_frames = num_of_frames + 1; |
if (/*(num_of_frames == 2) || (num_of_frames == 4) || (num_of_frames == 7) ||*/ (num_of_frames <= 10) || |
(num_of_frames == 14) || (num_of_frames == 18) || (num_of_frames == 23) || (num_of_frames == 28) || |
(num_of_frames == 34) || (num_of_frames == 40) || (num_of_frames == 47) || |
(num_of_frames == 54) || (num_of_frames == 62)) |
num_of_bd = 0; |
else |
num_of_bd = num_of_bd + 1; |
end |
// disable TX |
wait (wbm_working == 0); |
wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN, |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
@(posedge wb_clk); |
if(fail == 0) |
test_ok; |
else |
fail = 0; |
end |
|
|
//////////////////////////////////////////////////////////////////// |
//// //// |
//// Test transmit packets form 0 to (MINFL - 1) sizes at //// |
//// 8 TX buffer decriptors ( 100Mbps ). //// |
//// //// |
//////////////////////////////////////////////////////////////////// |
if (test_num == 7) // |
begin |
// TEST 7: TRANSMIT PACKETS FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 100Mbps ) |
test_name = "TEST 7: TRANSMIT PACKETS FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 100Mbps )"; |
`TIME; $display(" TEST 7: TRANSMIT PACKETS FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 100Mbps )"); |
|
// reset MAC registers |
hard_reset; |
// reset MAC and MII LOGIC with soft reset |
// reset_mac; |
// reset_mii; |
// set wb slave response |
wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries); |
|
max_tmp = 0; |
min_tmp = 0; |
// set 8 TX buffer descriptors - must be set before TX enable |
wait (wbm_working == 0); |
wbm_write(`ETH_TX_BD_NUM, 32'h8, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// enable TX, set full-duplex mode, padding and CRC appending |
wait (wbm_working == 0); |
wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_PAD | `ETH_MODER_FULLD | `ETH_MODER_CRCEN, |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// prepare two packets of MAXFL length |
wait (wbm_working == 0); |
wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC |
min_tmp = tmp[31:16]; |
st_data = 8'h12; |
set_tx_packet(`MEMORY_BASE, (max_tmp - 4), st_data); // length without CRC |
st_data = 8'h34; |
set_tx_packet((`MEMORY_BASE + max_tmp), (max_tmp - 4), st_data); // length without CRC |
// check WB INT signal |
if (wb_int !== 1'b0) |
begin |
test_fail("WB INT signal should not be set"); |
fail = fail + 1; |
end |
|
// write to phy's control register for 100Mbps |
#Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 set - speed 100 |
#Tp eth_phy.control_bit8_0 = 9'h1_00; // bit 6 reset - (10/100), bit 8 set - FD |
speed = 100; |
|
frame_started = 0; |
num_of_frames = 0; |
num_of_bd = 0; |
i_length = 0; // 0; |
while (i_length < 70) // (min_tmp - 4)) |
begin |
#1; |
// choose generating carrier sense and collision |
case (i_length[1:0]) |
2'h0: // Interrupt is generated |
begin |
// Reset_tx_bd nable interrupt generation |
// unmask interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY | |
`ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// not detect carrier sense in FD and no collision |
eth_phy.carrier_sense_tx_fd_detect(0); |
eth_phy.collision(0); |
end |
2'h1: // Interrupt is not generated |
begin |
// set_tx_bd enable interrupt generation |
// mask interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// detect carrier sense in FD and no collision |
eth_phy.carrier_sense_tx_fd_detect(1); |
eth_phy.collision(0); |
end |
2'h2: // Interrupt is not generated |
begin |
// set_tx_bd disable the interrupt generation |
// unmask interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY | |
`ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// not detect carrier sense in FD and set collision |
eth_phy.carrier_sense_tx_fd_detect(0); |
eth_phy.collision(1); |
end |
default: // 2'h3: // Interrupt is not generated |
begin |
// set_tx_bd disable the interrupt generation |
// mask interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// detect carrier sense in FD and set collision |
eth_phy.carrier_sense_tx_fd_detect(1); |
eth_phy.collision(1); |
end |
endcase |
#1; |
// first destination address on ethernet PHY |
eth_phy.set_tx_mem_addr(num_of_frames * 16); |
// SET packets and wrap bit |
// num_of_frames <= 9 => wrap set to TX BD 0 |
if (num_of_frames <= 9) |
begin |
tmp_len = i_length; // length of frame |
tmp_bd_num = 0; // TX BD number |
// if i_length[1] == 0 then enable interrupt generation otherwise disable it |
// if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp |
if (tmp_len[0] == 0) |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE); |
else |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp)); |
// set wrap bit |
set_tx_bd_wrap(0); |
end |
// 10 <= num_of_frames < 18 => wrap set to TX BD 3 |
else if ((num_of_frames == 10) || (num_of_frames == 14)) |
begin |
tmp_len = i_length; // length of frame |
tmp_bd_num = 0; // TX BD number |
while (tmp_bd_num < 4) // |
begin |
// if i_length[1] == 0 then enable interrupt generation otherwise disable it |
// if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp |
if (tmp_len[0] == 0) |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE); |
else |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp)); |
tmp_len = tmp_len + 1; |
// set TX BD number |
tmp_bd_num = tmp_bd_num + 1; |
end |
// set wrap bit |
set_tx_bd_wrap(3); |
end |
// 18 <= num_of_frames < 28 => wrap set to TX BD 4 |
else if ((num_of_frames == 18) || (num_of_frames == 23)) |
begin |
tmp_len = i_length; // length of frame |
tmp_bd_num = 0; // TX BD number |
while (tmp_bd_num < 5) // |
begin |
// if i_length[1] == 0 then enable interrupt generation otherwise disable it |
// if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp |
if (tmp_len[0] == 0) |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE); |
else |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp)); |
tmp_len = tmp_len + 1; |
// set TX BD number |
tmp_bd_num = tmp_bd_num + 1; |
end |
// set wrap bit |
set_tx_bd_wrap(4); |
end |
// 28 <= num_of_frames < 40 => wrap set to TX BD 5 |
else if ((num_of_frames == 28) || (num_of_frames == 34)) |
begin |
tmp_len = i_length; // length of frame |
tmp_bd_num = 0; // TX BD number |
while (tmp_bd_num < 6) // |
begin |
// if i_length[1] == 0 then enable interrupt generation otherwise disable it |
// if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp |
if (tmp_len[0] == 0) |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE); |
else |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp)); |
tmp_len = tmp_len + 1; |
// set TX BD number |
tmp_bd_num = tmp_bd_num + 1; |
end |
// set wrap bit |
set_tx_bd_wrap(5); |
end |
// 40 <= num_of_frames < 54 => wrap set to TX BD 6 |
else if ((num_of_frames == 40) || (num_of_frames == 47)) |
begin |
tmp_len = i_length; // length of frame |
tmp_bd_num = 0; // TX BD number |
while (tmp_bd_num < 7) // |
begin |
// if i_length[1] == 0 then enable interrupt generation otherwise disable it |
// if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp |
if (tmp_len[0] == 0) |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE); |
else |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp)); |
tmp_len = tmp_len + 1; |
// set TX BD number |
tmp_bd_num = tmp_bd_num + 1; |
end |
// set wrap bit |
set_tx_bd_wrap(6); |
end |
// 54 <= num_of_frames < 70 => wrap set to TX BD 7 |
else if ((num_of_frames == 54) || (num_of_frames == 62)) |
begin |
tmp_len = i_length; // length of frame |
tmp_bd_num = 0; // TX BD number |
while (tmp_bd_num < 8) // |
begin |
// if i_length[1] == 0 then enable interrupt generation otherwise disable it |
// if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp |
if (tmp_len[0] == 0) |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE); |
else |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp)); |
tmp_len = tmp_len + 1; |
// set TX BD number |
tmp_bd_num = tmp_bd_num + 1; |
end |
// set wrap bit |
set_tx_bd_wrap(7); |
end |
#1; |
// SET ready bit |
if (num_of_frames < 10) |
set_tx_bd_ready(0, 0); |
else if (num_of_frames < 14) |
set_tx_bd_ready((num_of_frames - 10), (num_of_frames - 10)); |
else if (num_of_frames < 18) |
set_tx_bd_ready((num_of_frames - 14), (num_of_frames - 14)); |
else if (num_of_frames < 23) |
set_tx_bd_ready((num_of_frames - 18), (num_of_frames - 18)); |
else if (num_of_frames < 28) |
set_tx_bd_ready((num_of_frames - 23), (num_of_frames - 23)); |
else if (num_of_frames < 34) |
set_tx_bd_ready((num_of_frames - 28), (num_of_frames - 28)); |
else if (num_of_frames < 40) |
set_tx_bd_ready((num_of_frames - 34), (num_of_frames - 34)); |
else if (num_of_frames < 47) |
set_tx_bd_ready((num_of_frames - 40), (num_of_frames - 40)); |
else if (num_of_frames < 54) |
set_tx_bd_ready((num_of_frames - 47), (num_of_frames - 47)); |
else if (num_of_frames < 62) |
set_tx_bd_ready((num_of_frames - 54), (num_of_frames - 54)); |
else if (num_of_frames < 70) |
set_tx_bd_ready((num_of_frames - 62), (num_of_frames - 62)); |
// CHECK END OF TRANSMITION |
frame_started = 0; |
if (num_of_frames >= 5) |
#1 check_tx_bd(num_of_bd, data); |
fork |
begin: fr_st1 |
wait (MTxEn === 1'b1); // start transmit |
frame_started = 1; |
end |
begin |
repeat (50) @(posedge mtx_clk); // Increased from 30 to 50 |
if (num_of_frames < 5) |
begin |
if (frame_started == 1) |
begin |
`TIME; $display("*E Frame should NOT start!"); |
end |
disable fr_st1; |
end |
else |
begin |
if (frame_started == 0) |
begin |
`TIME; $display("*W Frame should start!"); |
disable fr_st1; |
end |
end |
end |
join |
// check packets larger than 4 bytes |
if (num_of_frames >= 5) |
begin |
wait (MTxEn === 1'b0); // end transmit |
while (data[15] === 1) |
begin |
#1 check_tx_bd(num_of_bd, data); |
@(posedge wb_clk); |
end |
repeat (1) @(posedge wb_clk); |
// check length of a PACKET |
if (i_length <= (min_tmp - 4)) |
begin |
if (eth_phy.tx_len != min_tmp) |
begin |
test_fail("Wrong length of the packet out from MAC"); |
fail = fail + 1; |
end |
end |
else |
begin |
if (eth_phy.tx_len != (i_length + 4)) |
begin |
test_fail("Wrong length of the packet out from MAC"); |
fail = fail + 1; |
end |
end |
// check transmitted TX packet data |
if (i_length[0] == 0) |
begin |
#1 check_tx_packet(`MEMORY_BASE, (num_of_frames * 16), i_length, tmp); |
end |
else |
begin |
#1 check_tx_packet((`MEMORY_BASE + max_tmp), (num_of_frames * 16), i_length, tmp); |
end |
if (tmp > 0) |
begin |
test_fail("Wrong data of the transmitted packet"); |
fail = fail + 1; |
end |
// check transmited TX packet CRC |
if (num_of_frames < (min_tmp - 4)) |
#1 check_tx_crc((num_of_frames * 16), (min_tmp - 4), 1'b0, tmp); // length without CRC |
else |
#1 check_tx_crc((num_of_frames * 16), i_length, 1'b0, tmp); // length without CRC |
if (tmp > 0) |
begin |
test_fail("Wrong CRC of the transmitted packet"); |
fail = fail + 1; |
end |
end |
// check WB INT signal |
if ((i_length[1:0] == 2'h0) && (num_of_frames >= 5)) |
begin |
if (wb_int !== 1'b1) |
begin |
`TIME; $display("*E WB INT signal should be set"); |
test_fail("WB INT signal should be set"); |
fail = fail + 1; |
end |
end |
else |
begin |
if (wb_int !== 1'b0) |
begin |
`TIME; $display("*E WB INT signal should not be set"); |
test_fail("WB INT signal should not be set"); |
fail = fail + 1; |
end |
end |
// check TX buffer descriptor of a packet |
check_tx_bd(num_of_bd, data); |
if (num_of_frames >= 5) |
begin |
if (i_length[1] == 1'b0) // interrupt enabled |
begin |
if ( (data[15:0] !== 16'h7800) && // wrap bit |
(data[15:0] !== 16'h5800) ) // without wrap bit |
begin |
`TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]); |
test_fail("TX buffer descriptor status is not correct"); |
fail = fail + 1; |
end |
end |
else // interrupt not enabled |
begin |
if ( (data[15:0] !== 16'h3800) && // wrap bit |
(data[15:0] !== 16'h1800) ) // without wrap bit |
begin |
`TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]); |
test_fail("TX buffer descriptor status is not correct"); |
fail = fail + 1; |
end |
end |
end |
else |
begin |
if (data[15] !== 1'b1) |
begin |
`TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]); |
test_fail("TX buffer descriptor status is not correct"); |
fail = fail + 1; |
end |
end |
// clear TX BD with wrap bit |
if (num_of_frames == 63) |
clear_tx_bd(16, 16); |
// check interrupts |
wait (wbm_working == 0); |
wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if ( ((i_length[1:0] == 2'h0) || (i_length[1:0] == 2'h1)) && (num_of_frames >= 5) ) |
begin |
if ((data & `ETH_INT_TXB) !== 1'b1) |
begin |
`TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data); |
test_fail("Interrupt Transmit Buffer was not set"); |
fail = fail + 1; |
end |
if ((data & (~`ETH_INT_TXB)) !== 0) |
begin |
`TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data); |
test_fail("Other interrupts (except Transmit Buffer) were set"); |
fail = fail + 1; |
end |
end |
else |
begin |
if (data !== 0) |
begin |
`TIME; $display("*E Any of interrupts (except Transmit Buffer) was set, interrupt reg: %0h, len: %0h", data, i_length[1:0]); |
test_fail("Any of interrupts (except Transmit Buffer) was set"); |
fail = fail + 1; |
end |
end |
// clear interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// check WB INT signal |
if (wb_int !== 1'b0) |
begin |
test_fail("WB INT signal should not be set"); |
fail = fail + 1; |
end |
// INTERMEDIATE DISPLAYS |
if (i_length == 3) |
begin |
$display(" pads appending to packets is selected"); |
$display(" using 1 BD out of 8 BDs assigned to TX (wrap at 1st BD - TX BD 0)"); |
$display(" ->packets with lengths from %0d to %0d are not transmitted (length increasing by 1 byte)", |
0, 3); |
end |
else if (i_length == 9) |
begin |
$display(" using 1 BD out of 8 BDs assigned to TX (wrap at 1st BD - TX BD 0)"); |
$display(" ->packet with length 4 is not transmitted (length increasing by 1 byte)"); |
$display(" ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)", |
5, 9); |
end |
else if (i_length == 17) |
begin |
$display(" using 4 BDs out of 8 BDs assigned to TX (wrap at 4th BD - TX BD 3)"); |
$display(" ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)", |
10, 17); |
end |
else if (i_length == 27) |
begin |
$display(" using 5 BDs out of 8 BDs assigned to TX (wrap at 5th BD - TX BD 4)"); |
$display(" ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)", |
18, 27); |
end |
else if (i_length == 40) |
begin |
$display(" using 6 BDs out of 8 BDs assigned to TX (wrap at 6th BD - TX BD 5)"); |
$display(" ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)", |
28, 40); |
end |
else if (i_length == 54) |
begin |
$display(" using 7 BDs out of 8 BDs assigned to TX (wrap at 7th BD - TX BD 6)"); |
$display(" ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)", |
41, 54); |
end |
else if (i_length == 69) |
begin |
$display(" using 8 BDs out of 8 BDs assigned to TX (wrap at 8th BD - TX BD 7)"); |
$display(" ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)", |
55, 69); |
end |
// set length (loop variable) |
i_length = i_length + 1; |
// the number of frame transmitted |
num_of_frames = num_of_frames + 1; |
if (/*(num_of_frames == 2) || (num_of_frames == 4) || (num_of_frames == 7) ||*/ (num_of_frames <= 10) || |
(num_of_frames == 14) || (num_of_frames == 18) || (num_of_frames == 23) || (num_of_frames == 28) || |
(num_of_frames == 34) || (num_of_frames == 40) || (num_of_frames == 47) || |
(num_of_frames == 54) || (num_of_frames == 62)) |
num_of_bd = 0; |
else |
num_of_bd = num_of_bd + 1; |
end |
// disable TX |
wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN, |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
@(posedge wb_clk); |
if(fail == 0) |
test_ok; |
else |
fail = 0; |
end |
|
|
//////////////////////////////////////////////////////////////////// |
//// //// |
//// Test transmit packets (no pads) from 0 to (MINFL - 1) //// |
//// sizes at 8 TX buffer decriptors ( 10Mbps ). //// |
//// //// |
//////////////////////////////////////////////////////////////////// |
if (test_num == 8) // |
begin |
// TEST 8: TRANSMIT PACKETS (NO PADs) FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 10Mbps ) |
test_name = "TEST 8: TRANSMIT PACKETS (NO PADs) FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 10Mbps )"; |
`TIME; $display(" TEST 8: TRANSMIT PACKETS (NO PADs) FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 10Mbps )"); |
|
// reset MAC registers |
hard_reset; |
// reset MAC and MII LOGIC with soft reset |
// reset_mac; |
// reset_mii; |
// set wb slave response |
wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries); |
|
max_tmp = 0; |
min_tmp = 0; |
// set 8 TX buffer descriptors - must be set before TX enable |
wait (wbm_working == 0); |
wbm_write(`ETH_TX_BD_NUM, 32'h8, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// enable TX, set full-duplex mode, padding and CRC appending |
wait (wbm_working == 0); |
// wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_PAD | `ETH_MODER_FULLD | `ETH_MODER_CRCEN, |
wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD, |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// prepare two packets of MAXFL length |
wait (wbm_working == 0); |
wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC |
min_tmp = tmp[31:16]; |
st_data = 8'h12; |
set_tx_packet(`MEMORY_BASE, (max_tmp - 4), st_data); // length without CRC |
st_data = 8'h34; |
set_tx_packet((`MEMORY_BASE + max_tmp), (max_tmp - 4), st_data); // length without CRC |
// check WB INT signal |
if (wb_int !== 1'b0) |
begin |
test_fail("WB INT signal should not be set"); |
fail = fail + 1; |
end |
|
// write to phy's control register for 10Mbps |
#Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10 |
#Tp eth_phy.control_bit8_0 = 9'h1_00; // bit 6 reset - (10/100), bit 8 set - FD |
speed = 10; |
|
frame_started = 0; |
num_of_frames = 0; |
num_of_bd = 0; |
i_length = 0; // 0; |
while (i_length < 70) // (min_tmp - 4)) |
begin |
#1; |
// choose generating carrier sense and collision |
case (i_length[1:0]) |
2'h0: // Interrupt is generated |
begin |
// Reset_tx_bd nable interrupt generation |
// unmask interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY | |
`ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// not detect carrier sense in FD and no collision |
eth_phy.carrier_sense_tx_fd_detect(0); |
eth_phy.collision(0); |
end |
2'h1: // Interrupt is not generated |
begin |
// set_tx_bd enable interrupt generation |
// mask interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// detect carrier sense in FD and no collision |
eth_phy.carrier_sense_tx_fd_detect(1); |
eth_phy.collision(0); |
end |
2'h2: // Interrupt is not generated |
begin |
// set_tx_bd disable the interrupt generation |
// unmask interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY | |
`ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// not detect carrier sense in FD and set collision |
eth_phy.carrier_sense_tx_fd_detect(0); |
eth_phy.collision(1); |
end |
default: // 2'h3: // Interrupt is not generated |
begin |
// set_tx_bd disable the interrupt generation |
// mask interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// detect carrier sense in FD and set collision |
eth_phy.carrier_sense_tx_fd_detect(1); |
eth_phy.collision(1); |
end |
endcase |
// // append CRC |
// if ((i_length[0] == 1'b0) && (num_of_frames >= 6)) |
// begin |
// append_tx_crc(`MEMORY_BASE, i_length, 1'b0); |
// end |
#1; |
// first destination address on ethernet PHY |
eth_phy.set_tx_mem_addr(num_of_frames * 16); |
// SET packets and wrap bit |
// num_of_frames <= 9 => wrap set to TX BD 0 |
if (num_of_frames <= 5) |
begin |
tmp_len = i_length; // length of frame |
tmp_bd_num = 0; // TX BD number |
// if i_length[1] == 0 then enable interrupt generation otherwise disable it |
// if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp |
|
if (tmp_len[0] == 0) // CRC appended by 'HARDWARE' |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b0, 1'b1, `MEMORY_BASE); |
else |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b0, 1'b1, (`MEMORY_BASE + max_tmp)); |
// set wrap bit |
set_tx_bd_wrap(0); |
end |
else if (num_of_frames <= 9) |
begin |
tmp_len = i_length; // length of frame |
tmp_bd_num = 0; // TX BD number |
// if i_length[1] == 0 then enable interrupt generation otherwise disable it |
// if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp |
if (tmp_len[0] == 0) // CRC appended by 'SOFTWARE' |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b0, 1'b0, `MEMORY_BASE); |
else |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b0, 1'b1, (`MEMORY_BASE + max_tmp)); |
// set wrap bit |
set_tx_bd_wrap(0); |
end |
// 10 <= num_of_frames < 18 => wrap set to TX BD 3 |
else if ((num_of_frames == 10) || (num_of_frames == 14)) |
begin |
tmp_len = i_length; // length of frame |
tmp_bd_num = 0; // TX BD number |
while (tmp_bd_num < 4) |
begin |
// if i_length[1] == 0 then enable interrupt generation otherwise disable it |
// if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp |
if (tmp_len[0] == 0) |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b0, 1'b0, `MEMORY_BASE); |
else |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b0, 1'b1, (`MEMORY_BASE + max_tmp)); |
tmp_len = tmp_len + 1; |
// set TX BD number |
tmp_bd_num = tmp_bd_num + 1; |
end |
// set wrap bit |
set_tx_bd_wrap(3); |
end |
// 18 <= num_of_frames < 28 => wrap set to TX BD 4 |
else if ((num_of_frames == 18) || (num_of_frames == 23)) |
begin |
tmp_len = i_length; // length of frame |
tmp_bd_num = 0; // TX BD number |
while (tmp_bd_num < 5) // |
begin |
// if i_length[1] == 0 then enable interrupt generation otherwise disable it |
// if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp |
if (tmp_len[0] == 0) |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b0, 1'b0, `MEMORY_BASE); |
else // when (num_of_frames == 23), (i_length == 23) and therefor i_length[0] == 1 !!! |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], |
((num_of_frames == 23) && (tmp_bd_num == 0)), 1'b1, (`MEMORY_BASE + max_tmp)); |
|
tmp_len = tmp_len + 1; |
// set TX BD number |
tmp_bd_num = tmp_bd_num + 1; |
end |
// set wrap bit |
set_tx_bd_wrap(4); |
end |
// 28 <= num_of_frames < 40 => wrap set to TX BD 5 |
else if ((num_of_frames == 28) || (num_of_frames == 34)) |
begin |
tmp_len = i_length; // length of frame |
tmp_bd_num = 0; // TX BD number |
while (tmp_bd_num < 6) // |
begin |
// if i_length[1] == 0 then enable interrupt generation otherwise disable it |
// if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp |
if (tmp_len[0] == 0) |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b0, 1'b0, `MEMORY_BASE); |
else |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b0, 1'b1, (`MEMORY_BASE + max_tmp)); |
tmp_len = tmp_len + 1; |
// set TX BD number |
tmp_bd_num = tmp_bd_num + 1; |
end |
// set wrap bit |
set_tx_bd_wrap(5); |
end |
// 40 <= num_of_frames < 54 => wrap set to TX BD 6 |
else if ((num_of_frames == 40) || (num_of_frames == 47)) |
begin |
tmp_len = i_length; // length of frame |
tmp_bd_num = 0; // TX BD number |
while (tmp_bd_num < 7) // |
begin |
// if i_length[1] == 0 then enable interrupt generation otherwise disable it |
// if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp |
if (tmp_len[0] == 0) |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b0, 1'b0, `MEMORY_BASE); |
else |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b0, 1'b1, (`MEMORY_BASE + max_tmp)); |
tmp_len = tmp_len + 1; |
// set TX BD number |
tmp_bd_num = tmp_bd_num + 1; |
end |
// set wrap bit |
set_tx_bd_wrap(6); |
end |
// 54 <= num_of_frames < 70 => wrap set to TX BD 7 |
else if ((num_of_frames == 54) || (num_of_frames == 62)) |
begin |
tmp_len = i_length; // length of frame |
tmp_bd_num = 0; // TX BD number |
while (tmp_bd_num < 8) // |
begin |
// if i_length[1] == 0 then enable interrupt generation otherwise disable it |
// if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp |
if (tmp_len[0] == 0) |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b0, 1'b0, `MEMORY_BASE); |
else |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b0, 1'b1, (`MEMORY_BASE + max_tmp)); |
tmp_len = tmp_len + 1; |
// set TX BD number |
tmp_bd_num = tmp_bd_num + 1; |
end |
// set wrap bit |
set_tx_bd_wrap(7); |
end |
#1; |
// SET ready bit |
if (num_of_frames < 10) |
set_tx_bd_ready(0, 0); |
else if (num_of_frames < 14) |
set_tx_bd_ready((num_of_frames - 10), (num_of_frames - 10)); |
else if (num_of_frames < 18) |
set_tx_bd_ready((num_of_frames - 14), (num_of_frames - 14)); |
else if (num_of_frames < 23) |
set_tx_bd_ready((num_of_frames - 18), (num_of_frames - 18)); |
else if (num_of_frames < 28) |
set_tx_bd_ready((num_of_frames - 23), (num_of_frames - 23)); |
else if (num_of_frames < 34) |
set_tx_bd_ready((num_of_frames - 28), (num_of_frames - 28)); |
else if (num_of_frames < 40) |
set_tx_bd_ready((num_of_frames - 34), (num_of_frames - 34)); |
else if (num_of_frames < 47) |
set_tx_bd_ready((num_of_frames - 40), (num_of_frames - 40)); |
else if (num_of_frames < 54) |
set_tx_bd_ready((num_of_frames - 47), (num_of_frames - 47)); |
else if (num_of_frames < 62) |
set_tx_bd_ready((num_of_frames - 54), (num_of_frames - 54)); |
else if (num_of_frames < 70) |
set_tx_bd_ready((num_of_frames - 62), (num_of_frames - 62)); |
// CHECK END OF TRANSMITION |
frame_started = 0; |
if (num_of_frames >= 5) |
#1 check_tx_bd(num_of_bd, data); |
fork |
begin: fr_st2 |
wait (MTxEn === 1'b1); // start transmit |
frame_started = 1; |
end |
begin |
repeat (30) @(posedge mtx_clk); |
if (num_of_frames < 5) |
begin |
if (frame_started == 1) |
begin |
`TIME; $display("*E Frame should NOT start!"); |
end |
disable fr_st2; |
end |
else |
begin |
if (frame_started == 0) |
begin |
`TIME; $display("*W Frame should start!"); |
disable fr_st2; |
end |
end |
end |
join |
|
|
// check packets larger than 4 bytes |
if (num_of_frames >= 5) |
begin |
wait (MTxEn === 1'b0); // end transmit |
while (data[15] === 1) |
begin |
#1 check_tx_bd(num_of_bd, data); |
@(posedge wb_clk); |
end |
repeat (1) @(posedge wb_clk); |
|
|
// check length of a PACKET // Check this if it is OK igor |
if (num_of_frames < 6) |
begin |
if (eth_phy.tx_len != (i_length + 4)) |
begin |
`TIME; $display("*E Wrong length of the packet out from MAC"); |
test_fail("Wrong length of the packet out from MAC"); |
fail = fail + 1; |
end |
end |
else if (num_of_frames != 23) // 6 - 53 except 23 |
begin |
if (i_length[0] == 1'b0) |
begin |
if (eth_phy.tx_len != i_length) |
begin |
`TIME; $display("*E Wrong length of the packet out from MAC"); |
test_fail("Wrong length of the packet out from MAC"); |
fail = fail + 1; |
end |
end |
else |
begin |
if (eth_phy.tx_len != (i_length + 4)) |
begin |
`TIME; $display("*E Wrong length of the packet out from MAC"); |
test_fail("Wrong length of the packet out from MAC"); |
fail = fail + 1; |
end |
end |
end |
else // num_of_frames == 23 |
begin |
if (data[12]) // Padding |
begin |
if (eth_phy.tx_len != (64)) |
begin |
`TIME; $display("*E Wrong length of the packet out from MAC"); |
test_fail("Wrong length of the packet out from MAC"); |
fail = fail + 1; |
end |
end |
else |
begin |
if (eth_phy.tx_len != (i_length + 4)) |
begin |
`TIME; $display("*E Wrong length of the packet out from MAC"); |
test_fail("Wrong length of the packet out from MAC"); |
fail = fail + 1; |
end |
end |
end |
|
// check transmitted TX packet data |
if (i_length[0] == 0) |
begin |
#1 check_tx_packet(`MEMORY_BASE, (num_of_frames * 16), i_length, tmp); |
end |
else if (num_of_frames == 23) // i_length[0] == 1 here |
begin |
#1 check_tx_packet((`MEMORY_BASE + max_tmp), (num_of_frames * 16), i_length, tmp); |
#1 check_tx_packet( 0, (num_of_frames * 16 + i_length), (min_tmp - i_length - 4), tmp); |
end |
else |
begin |
#1 check_tx_packet((`MEMORY_BASE + max_tmp), (num_of_frames * 16), i_length, tmp); |
end |
if (tmp > 0) |
begin |
test_fail("Wrong data of the transmitted packet"); |
fail = fail + 1; |
end |
// check transmited TX packet CRC |
#1; |
if ((i_length[0] == 1'b0) && (num_of_frames >= 6)) |
begin |
end |
else |
check_tx_crc((num_of_frames * 16), (eth_phy.tx_len - 4), 1'b0, tmp); // length without CRC |
if (tmp > 0) |
begin |
test_fail("Wrong CRC of the transmitted packet"); |
fail = fail + 1; |
end |
end |
// check WB INT signal |
if ((i_length[1:0] == 2'h0) && (num_of_frames >= 5)) |
begin |
if (wb_int !== 1'b1) |
begin |
`TIME; $display("*E WB INT signal should be set"); |
test_fail("WB INT signal should be set"); |
fail = fail + 1; |
end |
end |
else |
begin |
if (wb_int !== 1'b0) |
begin |
`TIME; $display("*E WB INT signal should not be set"); |
test_fail("WB INT signal should not be set"); |
fail = fail + 1; |
end |
end |
// check TX buffer descriptor of a packet |
check_tx_bd(num_of_bd, data); |
|
if (num_of_frames >= 5) |
begin |
if ((i_length[1] == 1'b0) && (i_length[0] == 1'b0)) // interrupt enabled |
begin |
if ( (data[15:0] !== 16'h6000) && // wrap bit |
(data[15:0] !== 16'h4000) ) // without wrap bit |
begin |
`TIME; $display("*E TX buffer descriptor status is not correct 1: %0h", data[15:0]); |
test_fail("TX buffer descriptor status is not correct"); |
fail = fail + 1; |
end |
end |
else if ((i_length[1] == 1'b1) && (i_length[0] == 1'b0)) // interrupt not enabled |
begin |
if ( (data[15:0] !== 16'h2000) && // wrap bit |
(data[15:0] !== 16'h0000) ) // without wrap bit |
begin |
`TIME; $display("*E TX buffer descriptor status is not correct 2: %0h", data[15:0]); |
test_fail("TX buffer descriptor status is not correct"); |
fail = fail + 1; |
end |
end |
else if ((i_length[1] == 1'b0) && (i_length[0] == 1'b1)) // interrupt enabled |
begin |
if ( (data[15:0] !== 16'h6800) && // wrap bit |
(data[15:0] !== 16'h4800) ) // without wrap bit |
begin |
`TIME; $display("*E TX buffer descriptor status is not correct 3: %0h", data[15:0]); |
test_fail("TX buffer descriptor status is not correct"); |
fail = fail + 1; |
end |
end |
else if (num_of_frames != 23) // ((i_length[1] == 1'b1) && (i_length[0] == 1'b1)) // interrupt not enabled |
begin |
if ( (data[15:0] !== 16'h2800) && // wrap bit |
(data[15:0] !== 16'h0800) ) // without wrap bit |
begin |
`TIME; $display("*E TX buffer descriptor status is not correct 4: %0h", data[15:0]); |
test_fail("TX buffer descriptor status is not correct"); |
fail = fail + 1; |
end |
end |
else // ((num_of_frames != 23) && (i_length[1] == 1'b1) && (i_length[0] == 1'b1)) // interrupt not enabled |
begin |
if ( (data[15:0] !== 16'h3800) && // wrap bit |
(data[15:0] !== 16'h1800) ) // without wrap bit |
begin |
`TIME; $display("*E TX buffer descriptor status is not correct 5: %0h", data[15:0]); |
test_fail("TX buffer descriptor status is not correct"); |
fail = fail + 1; |
end |
end |
end |
else |
begin |
if (data[15] !== 1'b1) |
begin |
`TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]); |
test_fail("TX buffer descriptor status is not correct"); |
fail = fail + 1; |
end |
end |
// clear TX BD with wrap bit |
if (num_of_frames == 63) |
clear_tx_bd(16, 16); |
// check interrupts |
wait (wbm_working == 0); |
wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if ( ((i_length[1:0] == 2'h0) || (i_length[1:0] == 2'h1)) && (num_of_frames >= 5) ) |
begin |
if ((data & `ETH_INT_TXB) !== 1'b1) |
begin |
`TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data); |
test_fail("Interrupt Transmit Buffer was not set"); |
fail = fail + 1; |
end |
if ((data & (~`ETH_INT_TXB)) !== 0) |
begin |
`TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data); |
test_fail("Other interrupts (except Transmit Buffer) were set"); |
fail = fail + 1; |
end |
end |
else |
begin |
if (data !== 0) |
begin |
`TIME; $display("*E Any of interrupts (except Transmit Buffer) was set, interrupt reg: %0h, len: %0h", data, i_length[1:0]); |
test_fail("Any of interrupts (except Transmit Buffer) was set"); |
fail = fail + 1; |
end |
end |
// clear interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// check WB INT signal |
if (wb_int !== 1'b0) |
begin |
test_fail("WB INT signal should not be set"); |
fail = fail + 1; |
end |
// INTERMEDIATE DISPLAYS |
if (i_length == 3) |
begin |
$display(" pads appending to packets is not selected (except for 0x23)"); |
$display(" using 1 BD out of 8 BDs assigned to TX (wrap at 1st BD - TX BD 0)"); |
$display(" ->packets with lengths from %0d to %0d are not transmitted (length increasing by 1 byte)", |
0, 3); |
end |
else if (i_length == 9) |
begin |
$display(" using 1 BD out of 8 BDs assigned to TX (wrap at 1st BD - TX BD 0)"); |
$display(" ->packet with length 4 is not transmitted (length increasing by 1 byte)"); |
$display(" ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)", |
5, 9); |
end |
else if (i_length == 17) |
begin |
$display(" using 4 BDs out of 8 BDs assigned to TX (wrap at 4th BD - TX BD 3)"); |
$display(" ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)", |
10, 17); |
end |
else if (i_length == 27) |
begin |
$display(" using 5 BDs out of 8 BDs assigned to TX (wrap at 5th BD - TX BD 4)"); |
$display(" ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)", |
18, 27); |
end |
else if (i_length == 40) |
begin |
$display(" using 6 BDs out of 8 BDs assigned to TX (wrap at 6th BD - TX BD 5)"); |
$display(" ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)", |
28, 40); |
end |
else if (i_length == 54) |
begin |
$display(" using 7 BDs out of 8 BDs assigned to TX (wrap at 7th BD - TX BD 6)"); |
$display(" ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)", |
41, 54); |
end |
else if (i_length == 69) |
begin |
$display(" using 8 BDs out of 8 BDs assigned to TX (wrap at 8th BD - TX BD 7)"); |
$display(" ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)", |
55, 69); |
end |
// set length (loop variable) |
i_length = i_length + 1; |
// the number of frame transmitted |
num_of_frames = num_of_frames + 1; |
if (/*(num_of_frames == 2) || (num_of_frames == 4) || (num_of_frames == 7) ||*/ (num_of_frames <= 10) || |
(num_of_frames == 14) || (num_of_frames == 18) || (num_of_frames == 23) || (num_of_frames == 28) || |
(num_of_frames == 34) || (num_of_frames == 40) || (num_of_frames == 47) || |
(num_of_frames == 54) || (num_of_frames == 62)) |
num_of_bd = 0; |
else |
num_of_bd = num_of_bd + 1; |
end |
// disable TX |
wait (wbm_working == 0); |
wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN, |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
@(posedge wb_clk); |
if(fail == 0) |
test_ok; |
else |
fail = 0; |
end |
|
|
//////////////////////////////////////////////////////////////////// |
//// //// |
//// Test transmit packets (no pads) form 0 to (MINFL - 1) //// |
//// sizes at 8 TX buffer decriptors ( 100Mbps ). //// |
//// //// |
//////////////////////////////////////////////////////////////////// |
if (test_num == 9) // |
begin |
// TEST 9: TRANSMIT PACKETS (NO PADs) FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 100Mbps ) |
test_name = "TEST 9: TRANSMIT PACKETS (NO PADs) FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 100Mbps )"; |
`TIME; $display(" TEST 9: TRANSMIT PACKETS (NO PADs) FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 100Mbps )"); |
|
// reset MAC registers |
hard_reset; |
// reset MAC and MII LOGIC with soft reset |
// reset_mac; |
// reset_mii; |
// set wb slave response |
wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries); |
|
max_tmp = 0; |
min_tmp = 0; |
// set 8 TX buffer descriptors - must be set before TX enable |
wait (wbm_working == 0); |
wbm_write(`ETH_TX_BD_NUM, 32'h8, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// enable TX, set full-duplex mode, padding and CRC appending |
wait (wbm_working == 0); |
wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_PAD | `ETH_MODER_FULLD | `ETH_MODER_CRCEN, |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// prepare two packets of MAXFL length |
wait (wbm_working == 0); |
wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC |
min_tmp = tmp[31:16]; |
st_data = 8'h12; |
set_tx_packet(`MEMORY_BASE, (max_tmp - 4), st_data); // length without CRC |
st_data = 8'h34; |
set_tx_packet((`MEMORY_BASE + max_tmp), (max_tmp - 4), st_data); // length without CRC |
// check WB INT signal |
if (wb_int !== 1'b0) |
begin |
test_fail("WB INT signal should not be set"); |
fail = fail + 1; |
end |
|
// write to phy's control register for 100Mbps |
#Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 set - speed 100 |
#Tp eth_phy.control_bit8_0 = 9'h1_00; // bit 6 reset - (10/100), bit 8 set - FD |
speed = 100; |
|
frame_started = 0; |
num_of_frames = 0; |
num_of_bd = 0; |
i_length = 0; // 0; |
while (i_length < 70) // (min_tmp - 4)) |
begin |
#1; |
// choose generating carrier sense and collision |
case (i_length[1:0]) |
2'h0: // Interrupt is generated |
begin |
// Reset_tx_bd nable interrupt generation |
// unmask interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY | |
`ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// not detect carrier sense in FD and no collision |
eth_phy.carrier_sense_tx_fd_detect(0); |
eth_phy.collision(0); |
end |
2'h1: // Interrupt is not generated |
begin |
// set_tx_bd enable interrupt generation |
// mask interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// detect carrier sense in FD and no collision |
eth_phy.carrier_sense_tx_fd_detect(1); |
eth_phy.collision(0); |
end |
2'h2: // Interrupt is not generated |
begin |
// set_tx_bd disable the interrupt generation |
// unmask interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY | |
`ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// not detect carrier sense in FD and set collision |
eth_phy.carrier_sense_tx_fd_detect(0); |
eth_phy.collision(1); |
end |
default: // 2'h3: // Interrupt is not generated |
begin |
// set_tx_bd disable the interrupt generation |
// mask interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// detect carrier sense in FD and set collision |
eth_phy.carrier_sense_tx_fd_detect(1); |
eth_phy.collision(1); |
end |
endcase |
#1; |
// first destination address on ethernet PHY |
eth_phy.set_tx_mem_addr(num_of_frames * 16); |
// SET packets and wrap bit |
// num_of_frames <= 9 => wrap set to TX BD 0 |
if (num_of_frames <= 9) |
begin |
tmp_len = i_length; // length of frame |
tmp_bd_num = 0; // TX BD number |
// if i_length[1] == 0 then enable interrupt generation otherwise disable it |
// if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp |
if (tmp_len[0] == 0) |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE); |
else |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp)); |
// set wrap bit |
set_tx_bd_wrap(0); |
end |
// 10 <= num_of_frames < 18 => wrap set to TX BD 3 |
else if ((num_of_frames == 10) || (num_of_frames == 14)) |
begin |
tmp_len = i_length; // length of frame |
tmp_bd_num = 0; // TX BD number |
while (tmp_bd_num < 4) // |
begin |
// if i_length[1] == 0 then enable interrupt generation otherwise disable it |
// if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp |
if (tmp_len[0] == 0) |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE); |
else |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp)); |
tmp_len = tmp_len + 1; |
// set TX BD number |
tmp_bd_num = tmp_bd_num + 1; |
end |
// set wrap bit |
set_tx_bd_wrap(3); |
end |
// 18 <= num_of_frames < 28 => wrap set to TX BD 4 |
else if ((num_of_frames == 18) || (num_of_frames == 23)) |
begin |
tmp_len = i_length; // length of frame |
tmp_bd_num = 0; // TX BD number |
while (tmp_bd_num < 5) // |
begin |
// if i_length[1] == 0 then enable interrupt generation otherwise disable it |
// if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp |
if (tmp_len[0] == 0) |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE); |
else |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp)); |
tmp_len = tmp_len + 1; |
// set TX BD number |
tmp_bd_num = tmp_bd_num + 1; |
end |
// set wrap bit |
set_tx_bd_wrap(4); |
end |
// 28 <= num_of_frames < 40 => wrap set to TX BD 5 |
else if ((num_of_frames == 28) || (num_of_frames == 34)) |
begin |
tmp_len = i_length; // length of frame |
tmp_bd_num = 0; // TX BD number |
while (tmp_bd_num < 6) // |
begin |
// if i_length[1] == 0 then enable interrupt generation otherwise disable it |
// if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp |
if (tmp_len[0] == 0) |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE); |
else |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp)); |
tmp_len = tmp_len + 1; |
// set TX BD number |
tmp_bd_num = tmp_bd_num + 1; |
end |
// set wrap bit |
set_tx_bd_wrap(5); |
end |
// 40 <= num_of_frames < 54 => wrap set to TX BD 6 |
else if ((num_of_frames == 40) || (num_of_frames == 47)) |
begin |
tmp_len = i_length; // length of frame |
tmp_bd_num = 0; // TX BD number |
while (tmp_bd_num < 7) // |
begin |
// if i_length[1] == 0 then enable interrupt generation otherwise disable it |
// if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp |
if (tmp_len[0] == 0) |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE); |
else |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp)); |
tmp_len = tmp_len + 1; |
// set TX BD number |
tmp_bd_num = tmp_bd_num + 1; |
end |
// set wrap bit |
set_tx_bd_wrap(6); |
end |
// 54 <= num_of_frames < 70 => wrap set to TX BD 7 |
else if ((num_of_frames == 54) || (num_of_frames == 62)) |
begin |
tmp_len = i_length; // length of frame |
tmp_bd_num = 0; // TX BD number |
while (tmp_bd_num < 8) // |
begin |
// if i_length[1] == 0 then enable interrupt generation otherwise disable it |
// if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp |
if (tmp_len[0] == 0) |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE); |
else |
set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp)); |
tmp_len = tmp_len + 1; |
// set TX BD number |
tmp_bd_num = tmp_bd_num + 1; |
end |
// set wrap bit |
set_tx_bd_wrap(7); |
end |
#1; |
// SET ready bit |
if (num_of_frames < 10) |
set_tx_bd_ready(0, 0); |
else if (num_of_frames < 14) |
set_tx_bd_ready((num_of_frames - 10), (num_of_frames - 10)); |
else if (num_of_frames < 18) |
set_tx_bd_ready((num_of_frames - 14), (num_of_frames - 14)); |
else if (num_of_frames < 23) |
set_tx_bd_ready((num_of_frames - 18), (num_of_frames - 18)); |
else if (num_of_frames < 28) |
set_tx_bd_ready((num_of_frames - 23), (num_of_frames - 23)); |
else if (num_of_frames < 34) |
set_tx_bd_ready((num_of_frames - 28), (num_of_frames - 28)); |
else if (num_of_frames < 40) |
set_tx_bd_ready((num_of_frames - 34), (num_of_frames - 34)); |
else if (num_of_frames < 47) |
set_tx_bd_ready((num_of_frames - 40), (num_of_frames - 40)); |
else if (num_of_frames < 54) |
set_tx_bd_ready((num_of_frames - 47), (num_of_frames - 47)); |
else if (num_of_frames < 62) |
set_tx_bd_ready((num_of_frames - 54), (num_of_frames - 54)); |
else if (num_of_frames < 70) |
set_tx_bd_ready((num_of_frames - 62), (num_of_frames - 62)); |
// CHECK END OF TRANSMITION |
frame_started = 0; |
if (num_of_frames >= 5) |
#1 check_tx_bd(num_of_bd, data); |
fork |
begin: fr_st3 |
wait (MTxEn === 1'b1); // start transmit |
frame_started = 1; |
end |
begin |
repeat (50) @(posedge mtx_clk); |
$display("(%0t) num_of_frames = 0x%0x", $time, num_of_frames); |
if (num_of_frames < 5) |
begin |
if (frame_started == 1) |
begin |
`TIME; $display("*E Frame should NOT start!"); |
end |
disable fr_st3; |
end |
else |
begin |
if (frame_started == 0) |
begin |
`TIME; $display("*W Frame should start!"); |
#500 $stop; |
disable fr_st3; |
end |
end |
end |
join |
// check packets larger than 4 bytes |
if (num_of_frames >= 5) |
begin |
wait (MTxEn === 1'b0); // end transmit |
while (data[15] === 1) |
begin |
#1 check_tx_bd(num_of_bd, data); |
@(posedge wb_clk); |
end |
repeat (1) @(posedge wb_clk); |
// check length of a PACKET |
if ((num_of_frames + 4) < 64) |
begin |
if (eth_phy.tx_len != 64) |
begin |
`TIME; $display("*E Wrong length of the packet out from MAC"); |
test_fail("Wrong length of the packet out from MAC"); |
fail = fail + 1; |
end |
end |
else |
begin |
if (eth_phy.tx_len != (i_length + 4)) |
begin |
`TIME; $display("*E Wrong length of the packet out from MAC"); |
test_fail("Wrong length of the packet out from MAC"); |
fail = fail + 1; |
end |
end |
// check transmitted TX packet data |
if (i_length[0] == 0) |
begin |
#1 check_tx_packet(`MEMORY_BASE, (num_of_frames * 16), i_length, tmp); |
end |
else |
begin |
#1 check_tx_packet((`MEMORY_BASE + max_tmp), (num_of_frames * 16), i_length, tmp); |
end |
if (tmp > 0) |
begin |
test_fail("Wrong data of the transmitted packet"); |
fail = fail + 1; |
end |
// check transmited TX packet CRC |
#1 check_tx_crc((num_of_frames * 16), (eth_phy.tx_len - 4), 1'b0, tmp); // length without CRC |
if (tmp > 0) |
begin |
test_fail("Wrong CRC of the transmitted packet"); |
fail = fail + 1; |
end |
end |
// check WB INT signal |
if ((i_length[1:0] == 2'h0) && (num_of_frames >= 5)) |
begin |
if (wb_int !== 1'b1) |
begin |
`TIME; $display("*E WB INT signal should be set"); |
test_fail("WB INT signal should be set"); |
fail = fail + 1; |
end |
end |
else |
begin |
if (wb_int !== 1'b0) |
begin |
`TIME; $display("*E WB INT signal should not be set"); |
test_fail("WB INT signal should not be set"); |
fail = fail + 1; |
end |
end |
// check TX buffer descriptor of a packet |
check_tx_bd(num_of_bd, data); |
if (num_of_frames >= 5) |
begin |
if (i_length[1] == 1'b0) // interrupt enabled |
begin |
if ( (data[15:0] !== 16'h7800) && // wrap bit |
(data[15:0] !== 16'h5800) ) // without wrap bit |
begin |
`TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]); |
test_fail("TX buffer descriptor status is not correct"); |
fail = fail + 1; |
end |
end |
else // interrupt not enabled |
begin |
if ( (data[15:0] !== 16'h3800) && // wrap bit |
(data[15:0] !== 16'h1800) ) // without wrap bit |
begin |
`TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]); |
test_fail("TX buffer descriptor status is not correct"); |
fail = fail + 1; |
end |
end |
end |
else |
begin |
if (data[15] !== 1'b1) |
begin |
`TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]); |
test_fail("TX buffer descriptor status is not correct"); |
fail = fail + 1; |
end |
end |
// clear TX BD with wrap bit |
if (num_of_frames == 63) |
clear_tx_bd(16, 16); |
// check interrupts |
wait (wbm_working == 0); |
wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if ( ((i_length[1:0] == 2'h0) || (i_length[1:0] == 2'h1)) && (num_of_frames >= 5) ) |
begin |
if ((data & `ETH_INT_TXB) !== 1'b1) |
begin |
`TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data); |
test_fail("Interrupt Transmit Buffer was not set"); |
fail = fail + 1; |
end |
if ((data & (~`ETH_INT_TXB)) !== 0) |
begin |
`TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data); |
test_fail("Other interrupts (except Transmit Buffer) were set"); |
fail = fail + 1; |
end |
end |
else |
begin |
if (data !== 0) |
begin |
`TIME; $display("*E Any of interrupts (except Transmit Buffer) was set, interrupt reg: %0h, len: %0h", data, i_length[1:0]); |
test_fail("Any of interrupts (except Transmit Buffer) was set"); |
fail = fail + 1; |
end |
end |
// clear interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// check WB INT signal |
if (wb_int !== 1'b0) |
begin |
test_fail("WB INT signal should not be set"); |
fail = fail + 1; |
end |
// INTERMEDIATE DISPLAYS |
if (i_length == 3) |
begin |
$display(" pads appending to packets is selected"); |
$display(" using 1 BD out of 8 BDs assigned to TX (wrap at 1st BD - TX BD 0)"); |
$display(" ->packets with lengths from %0d to %0d are not transmitted (length increasing by 1 byte)", |
0, 3); |
end |
else if (i_length == 9) |
begin |
$display(" using 1 BD out of 8 BDs assigned to TX (wrap at 1st BD - TX BD 0)"); |
$display(" ->packet with length 4 is not transmitted (length increasing by 1 byte)"); |
$display(" ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)", |
5, 9); |
end |
else if (i_length == 17) |
begin |
$display(" using 4 BDs out of 8 BDs assigned to TX (wrap at 4th BD - TX BD 3)"); |
$display(" ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)", |
10, 17); |
end |
else if (i_length == 27) |
begin |
$display(" using 5 BDs out of 8 BDs assigned to TX (wrap at 5th BD - TX BD 4)"); |
$display(" ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)", |
18, 27); |
end |
else if (i_length == 40) |
begin |
$display(" using 6 BDs out of 8 BDs assigned to TX (wrap at 6th BD - TX BD 5)"); |
$display(" ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)", |
28, 40); |
end |
else if (i_length == 54) |
begin |
$display(" using 7 BDs out of 8 BDs assigned to TX (wrap at 7th BD - TX BD 6)"); |
$display(" ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)", |
41, 54); |
end |
else if (i_length == 69) |
begin |
$display(" using 8 BDs out of 8 BDs assigned to TX (wrap at 8th BD - TX BD 7)"); |
$display(" ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)", |
55, 69); |
end |
// set length (loop variable) |
i_length = i_length + 1; |
// the number of frame transmitted |
num_of_frames = num_of_frames + 1; |
if (/*(num_of_frames == 2) || (num_of_frames == 4) || (num_of_frames == 7) ||*/ (num_of_frames <= 10) || |
(num_of_frames == 14) || (num_of_frames == 18) || (num_of_frames == 23) || (num_of_frames == 28) || |
(num_of_frames == 34) || (num_of_frames == 40) || (num_of_frames == 47) || |
(num_of_frames == 54) || (num_of_frames == 62)) |
num_of_bd = 0; |
else |
num_of_bd = num_of_bd + 1; |
end |
// disable TX |
wait (wbm_working == 0); |
wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN, |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
@(posedge wb_clk); |
if(fail == 0) |
test_ok; |
else |
fail = 0; |
end |
|
|
//////////////////////////////////////////////////////////////////// |
//// //// |
//// Test transmit packets across MAXFL value at //// |
//// 13 TX buffer decriptors ( 10Mbps ). //// |
//// //// |
//////////////////////////////////////////////////////////////////// |
if (test_num == 10) // without and with padding |
begin |
// TEST 10: TRANSMIT PACKETS ACROSS MAXFL VALUE AT 13 TX BDs ( 10Mbps ) |
test_name = "TEST 10: TRANSMIT PACKETS ACROSS MAXFL VALUE AT 13 TX BDs ( 10Mbps )"; |
`TIME; $display(" TEST 10: TRANSMIT PACKETS ACROSS MAXFL VALUE AT 13 TX BDs ( 10Mbps )"); |
|
// reset MAC registers |
hard_reset; |
// set wb slave response |
wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries); |
|
max_tmp = 0; |
min_tmp = 0; |
num_of_frames = 0; |
num_of_bd = 0; |
// set 13 TX buffer descriptors - must be set before TX enable |
wait (wbm_working == 0); |
wbm_write(`ETH_TX_BD_NUM, 32'hD, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// enable TX, set full-duplex mode, NO padding and CRC appending |
wait (wbm_working == 0); |
wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN, |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// prepare a packet of MAXFL + 10 length |
wait (wbm_working == 0); |
wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC |
min_tmp = tmp[31:16]; |
st_data = 8'hA3; |
set_tx_packet(`MEMORY_BASE, (max_tmp + 10), st_data); // length without CRC |
// check WB INT signal |
if (wb_int !== 1'b0) |
begin |
test_fail("WB INT signal should not be set"); |
fail = fail + 1; |
end |
|
// write to phy's control register for 10Mbps |
#Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10 |
#Tp eth_phy.control_bit8_0 = 9'h1_00; // bit 6 reset - (10/100), bit 8 set - FD |
speed = 10; |
|
i_length = (max_tmp - 5); |
while (num_of_bd <= 3) |
begin |
// unmask interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY | |
`ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// not detect carrier sense in FD and no collision |
eth_phy.carrier_sense_tx_fd_detect(0); |
eth_phy.collision(0); |
// first destination address on ethernet PHY |
eth_phy.set_tx_mem_addr(0); |
|
if (num_of_bd == 0) |
begin |
set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, `MEMORY_BASE); |
set_tx_bd(1, 1, i_length+1, 1'b1, 1'b1, 1'b1, `MEMORY_BASE); |
set_tx_bd(2, 2, i_length+2, 1'b1, 1'b1, 1'b1, `MEMORY_BASE); |
set_tx_bd_wrap(2); |
set_tx_bd_ready(0, 0); |
end |
else if (num_of_bd == 1) |
set_tx_bd_ready(1, 1); |
else if (num_of_bd == 2) |
set_tx_bd_ready(2, 2); |
else if (num_of_bd == 3) |
begin |
set_tx_bd(0, 0, 100, 1'b1, 1'b1, 1'b1, `MEMORY_BASE); |
set_tx_bd_wrap(2); |
set_tx_bd_ready(0, 0); |
i_length = 96; |
end |
|
|
// CHECK END OF TRANSMITION |
check_tx_bd(num_of_bd, data); |
wait (MTxEn === 1'b1); // start transmit |
check_tx_bd(num_of_bd, data); |
if (data[15] !== 1) |
begin |
test_fail("Wrong buffer descriptor's ready bit read out from MAC"); |
fail = fail + 1; |
end |
wait (MTxEn === 1'b0); // end transmit |
while (data[15] === 1) |
begin |
check_tx_bd(num_of_bd, data); |
@(posedge wb_clk); |
end |
repeat (1) @(posedge wb_clk); |
// check length of a PACKET |
tmp_len = eth_phy.tx_len; |
#1; |
if (tmp_len != (i_length + 4)) |
begin |
test_fail("Wrong length of the packet out from MAC"); |
fail = fail + 1; |
end |
|
// check transmitted TX packet data |
if ((i_length + 4) == 100) |
check_tx_packet(`MEMORY_BASE, 0, 100 - 4, tmp); |
else if ((i_length + 4) <= max_tmp) |
check_tx_packet(`MEMORY_BASE, 0, i_length, tmp); |
else |
check_tx_packet(`MEMORY_BASE, 0, max_tmp - 4, tmp); |
|
if (tmp > 0) |
begin |
test_fail("Wrong data of the transmitted packet"); |
fail = fail + 1; |
end |
|
// check transmited TX packet CRC |
if ((i_length + 4) == 100) |
check_tx_crc(0, 100, 1'b0, tmp); // length without CRC |
else if ((i_length + 4) <= max_tmp) |
check_tx_crc(0, i_length, 1'b0, tmp); // length without CRC |
|
if (tmp > 0) |
begin |
test_fail("Wrong CRC of the transmitted packet"); |
fail = fail + 1; |
end |
|
if (wb_int !== 1'b1) |
begin |
`TIME; $display("*E WB INT signal should be set"); |
test_fail("WB INT signal should be set"); |
fail = fail + 1; |
end |
|
check_tx_bd(num_of_bd, data); |
if ( ((data[15:0] !== 16'h7800) && (num_of_bd == 2)) || // wrap bit |
((data[15:0] !== 16'h5800) && (num_of_bd < 2)) ) // without wrap bit |
begin |
`TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]); |
test_fail("TX buffer descriptor status is not correct"); |
fail = fail + 1; |
end |
|
// check interrupts |
wait (wbm_working == 0); |
wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if ((data & `ETH_INT_TXB) !== `ETH_INT_TXB) |
begin |
`TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data); |
test_fail("Interrupt Transmit Buffer was not set"); |
fail = fail + 1; |
end |
if ((data & (~`ETH_INT_TXB)) !== 0) |
begin |
`TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data); |
test_fail("Other interrupts (except Transmit Buffer) were set"); |
fail = fail + 1; |
end |
|
// clear interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// check WB INT signal |
if (wb_int !== 1'b0) |
begin |
test_fail("WB INT signal should not be set"); |
fail = fail + 1; |
end |
|
// INTERMEDIATE DISPLAYS |
if (num_of_bd == 0) |
$display(" ->packet with length %0d sent", (i_length + 4)); |
else if (num_of_bd == 1) |
$display(" ->packet with length %0d sent", (i_length + 4)); |
else if (num_of_bd == 2) |
$display(" ->packet with length %0d sent", (i_length + 4)); |
else if (num_of_bd == 3) |
$display(" ->packet with length %0d sent", (104)); |
// set length (loop variable) |
i_length = i_length + 1; |
// the number of frame transmitted |
num_of_frames = num_of_frames + 1; |
num_of_bd = num_of_bd + 1; |
@(posedge wb_clk); |
end |
// disable TX |
wait (wbm_working == 0); |
wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN, |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
@(posedge wb_clk); |
if(fail == 0) |
test_ok; |
else |
fail = 0; |
end |
|
|
//////////////////////////////////////////////////////////////////// |
//// //// |
//// Test transmit packets across MAXFL value at //// |
//// 13 TX buffer decriptors ( 100Mbps ). //// |
//// //// |
//////////////////////////////////////////////////////////////////// |
if (test_num == 11) // without and with padding |
begin |
// TEST 11: TRANSMIT PACKETS ACROSS MAXFL VALUE AT 13 TX BDs ( 100Mbps ) |
test_name = "TEST 11: TRANSMIT PACKETS ACROSS MAXFL VALUE AT 13 TX BDs ( 100Mbps )"; |
`TIME; $display(" TEST 11: TRANSMIT PACKETS ACROSS MAXFL VALUE AT 13 TX BDs ( 100Mbps )"); |
|
// reset MAC registers |
hard_reset; |
// set wb slave response |
wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries); |
|
max_tmp = 0; |
min_tmp = 0; |
num_of_frames = 0; |
num_of_bd = 0; |
// set 13 TX buffer descriptors - must be set before TX enable |
wait (wbm_working == 0); |
wbm_write(`ETH_TX_BD_NUM, 32'hD, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// enable TX, set full-duplex mode, NO padding and CRC appending |
wait (wbm_working == 0); |
wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN, |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// prepare a packet of MAXFL + 10 length |
wait (wbm_working == 0); |
wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC |
min_tmp = tmp[31:16]; |
st_data = 8'hA3; |
set_tx_packet(`MEMORY_BASE, (max_tmp + 10), st_data); // length without CRC |
// check WB INT signal |
if (wb_int !== 1'b0) |
begin |
test_fail("WB INT signal should not be set"); |
fail = fail + 1; |
end |
|
// write to phy's control register for 10Mbps |
#Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 reset - speed 100 |
#Tp eth_phy.control_bit8_0 = 9'h1_00; // bit 6 reset - (10/100), bit 8 set - FD |
speed = 100; |
|
i_length = (max_tmp - 5); |
while (num_of_bd <= 3) |
begin |
// unmask interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY | |
`ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// not detect carrier sense in FD and no collision |
eth_phy.carrier_sense_tx_fd_detect(0); |
eth_phy.collision(0); |
// first destination address on ethernet PHY |
eth_phy.set_tx_mem_addr(0); |
|
if (num_of_bd == 0) |
begin |
set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, `MEMORY_BASE); |
set_tx_bd(1, 1, i_length+1, 1'b1, 1'b1, 1'b1, `MEMORY_BASE); |
set_tx_bd(2, 2, i_length+2, 1'b1, 1'b1, 1'b1, `MEMORY_BASE); |
set_tx_bd_wrap(2); |
set_tx_bd_ready(0, 0); |
end |
else if (num_of_bd == 1) |
set_tx_bd_ready(1, 1); |
else if (num_of_bd == 2) |
set_tx_bd_ready(2, 2); |
else if (num_of_bd == 3) |
begin |
set_tx_bd(0, 0, 100, 1'b1, 1'b1, 1'b1, `MEMORY_BASE); |
set_tx_bd_wrap(2); |
set_tx_bd_ready(0, 0); |
i_length = 96; |
end |
|
|
// CHECK END OF TRANSMITION |
check_tx_bd(num_of_bd, data); |
wait (MTxEn === 1'b1); // start transmit |
check_tx_bd(num_of_bd, data); |
if (data[15] !== 1) |
begin |
test_fail("Wrong buffer descriptor's ready bit read out from MAC"); |
fail = fail + 1; |
end |
wait (MTxEn === 1'b0); // end transmit |
while (data[15] === 1) |
begin |
check_tx_bd(num_of_bd, data); |
@(posedge wb_clk); |
end |
repeat (1) @(posedge wb_clk); |
repeat (10) @(posedge mtx_clk); |
// check length of a PACKET |
tmp_len = eth_phy.tx_len; |
#1; |
if (tmp_len != (i_length + 4)) |
begin |
test_fail("Wrong length of the packet out from MAC"); |
fail = fail + 1; |
end |
|
// check transmitted TX packet data |
if ((i_length + 4) == 100) |
check_tx_packet(`MEMORY_BASE, 0, 100 - 4, tmp); |
else if ((i_length + 4) <= max_tmp) |
check_tx_packet(`MEMORY_BASE, 0, i_length, tmp); |
else |
check_tx_packet(`MEMORY_BASE, 0, max_tmp - 4, tmp); |
|
if (tmp > 0) |
begin |
test_fail("Wrong data of the transmitted packet"); |
fail = fail + 1; |
end |
|
// check transmited TX packet CRC |
if ((i_length + 4) == 100) |
check_tx_crc(0, 100, 1'b0, tmp); // length without CRC |
else if ((i_length + 4) <= max_tmp) |
check_tx_crc(0, i_length, 1'b0, tmp); // length without CRC |
|
if (tmp > 0) |
begin |
test_fail("Wrong CRC of the transmitted packet"); |
fail = fail + 1; |
end |
|
if (wb_int !== 1'b1) |
begin |
`TIME; $display("*E WB INT signal should be set"); |
test_fail("WB INT signal should be set"); |
fail = fail + 1; |
end |
|
check_tx_bd(num_of_bd, data); |
if ( ((data[15:0] !== 16'h7800) && (num_of_bd == 2)) || // wrap bit |
((data[15:0] !== 16'h5800) && (num_of_bd < 2)) ) // without wrap bit |
begin |
`TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]); |
test_fail("TX buffer descriptor status is not correct"); |
fail = fail + 1; |
end |
|
// check interrupts |
wait (wbm_working == 0); |
wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if ((data & `ETH_INT_TXB) !== `ETH_INT_TXB) |
begin |
`TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data); |
test_fail("Interrupt Transmit Buffer was not set"); |
fail = fail + 1; |
end |
if ((data & (~`ETH_INT_TXB)) !== 0) |
begin |
`TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data); |
test_fail("Other interrupts (except Transmit Buffer) were set"); |
fail = fail + 1; |
end |
|
// clear interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// check WB INT signal |
if (wb_int !== 1'b0) |
begin |
test_fail("WB INT signal should not be set"); |
fail = fail + 1; |
end |
|
// INTERMEDIATE DISPLAYS |
if (num_of_bd == 0) |
$display(" ->packet with length %0d sent", (i_length + 4)); |
else if (num_of_bd == 1) |
$display(" ->packet with length %0d sent", (i_length + 4)); |
else if (num_of_bd == 2) |
$display(" ->packet with length %0d sent", (i_length + 4)); |
else if (num_of_bd == 3) |
$display(" ->packet with length %0d sent", (104)); |
// set length (loop variable) |
i_length = i_length + 1; |
// the number of frame transmitted |
num_of_frames = num_of_frames + 1; |
num_of_bd = num_of_bd + 1; |
@(posedge wb_clk); |
end |
// disable TX |
wait (wbm_working == 0); |
wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN, |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
@(posedge wb_clk); |
if(fail == 0) |
test_ok; |
else |
fail = 0; |
end |
|
|
|
|
//////////////////////////////////////////////////////////////////// |
//// //// |
//// Test transmit packets across changed MAXFL value at //// |
//// 47 TX buffer decriptors ( 10Mbps ). //// |
//// //// |
//////////////////////////////////////////////////////////////////// |
if (test_num == 12) // without and with padding |
begin |
// TEST 12: TRANSMIT PACKETS ACROSS CHANGED MAXFL VALUE AT 13 TX BDs ( 10Mbps ) |
test_name = "TEST 12: TRANSMIT PACKETS ACROSS CHANGED MAXFL VALUE AT 13 TX BDs ( 10Mbps )"; |
`TIME; $display(" TEST 12: TRANSMIT PACKETS ACROSS CHANGED MAXFL VALUE AT 13 TX BDs ( 10Mbps )"); |
|
// reset MAC registers |
hard_reset; |
wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries); |
|
max_tmp = 0; |
min_tmp = 0; |
num_of_frames = 0; |
num_of_bd = 0; |
// set 47 TX buffer descriptors - must be set before TX enable |
wait (wbm_working == 0); |
wbm_write(`ETH_TX_BD_NUM, 32'h2F, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// prepare a packet of MAXFL + 10 length |
wait (wbm_working == 0); |
wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC |
min_tmp = tmp[31:16]; |
// change MAXFL value |
max_tmp = min_tmp + 53; |
wait (wbm_working == 0); |
wbm_write(`ETH_PACKETLEN, {min_tmp, max_tmp}, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
st_data = 8'h62; |
set_tx_packet(`MEMORY_BASE, max_tmp, st_data); // length with CRC |
wait (wbm_working == 0); |
wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD, |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// check WB INT signal |
if (wb_int !== 1'b0) |
begin |
test_fail("WB INT signal should not be set"); |
fail = fail + 1; |
end |
|
// write to phy's control register for 10Mbps |
#Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10 |
#Tp eth_phy.control_bit8_0 = 9'h1_00; // bit 6 reset - (10/100), bit 8 set - FD |
speed = 10; |
|
i_length = (max_tmp - 5); // (max_tmp - 1); // not (max_tmp - 5) because NO automatic CRC appending |
while (i_length <= (max_tmp - 3)) // (max_tmp + 1)) // (max_tmp) is the limit |
begin |
wait (wbm_working == 0); |
wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY | |
`ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// not detect carrier sense in FD and no collision |
eth_phy.carrier_sense_tx_fd_detect(0); |
eth_phy.collision(0); |
// first destination address on ethernet PHY |
eth_phy.set_tx_mem_addr(0); |
// prepare BDs |
if (num_of_bd == 0) |
begin |
set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, `MEMORY_BASE); |
set_tx_bd(1, 1, i_length+1, 1'b1, 1'b1, 1'b1, `MEMORY_BASE); |
set_tx_bd(2, 2, i_length+2, 1'b1, 1'b1, 1'b1, `MEMORY_BASE); |
set_tx_bd_wrap(2); |
set_tx_bd_ready(0, 0); |
end |
else if (num_of_bd == 1) |
set_tx_bd_ready(1, 1); |
else if (num_of_bd == 2) |
set_tx_bd_ready(2, 2); |
// CHECK END OF TRANSMITION |
check_tx_bd(num_of_bd, data); |
wait (MTxEn === 1'b1); // start transmit |
check_tx_bd(num_of_bd, data); |
if (data[15] !== 1) |
begin |
test_fail("Wrong buffer descriptor's ready bit read out from MAC"); |
fail = fail + 1; |
end |
wait (MTxEn === 1'b0); // end transmit |
while (data[15] === 1) |
begin |
check_tx_bd(num_of_bd, data); |
@(posedge wb_clk); |
end |
repeat (5) @(posedge mtx_clk); |
// check length of a PACKET |
tmp_len = eth_phy.tx_len; |
#1; |
if (tmp_len != (i_length + 4)) |
begin |
test_fail("Wrong length of the packet out from MAC"); |
fail = fail + 1; |
end |
// checking packet |
check_tx_packet(`MEMORY_BASE, 0, i_length, tmp); |
if (tmp > 0) |
begin |
test_fail("Wrong data of the transmitted packet"); |
fail = fail + 1; |
end |
// check transmited TX packet CRC |
if (num_of_bd !== 2) |
check_tx_crc(0, i_length, 1'b0, tmp); // length without CRC |
if (tmp > 0) |
begin |
test_fail("Wrong CRC of the transmitted packet"); |
fail = fail + 1; |
end |
// check WB INT signal |
if (wb_int !== 1'b1) |
begin |
`TIME; $display("*E WB INT signal should be set"); |
test_fail("WB INT signal should be set"); |
fail = fail + 1; |
end |
// check TX buffer descriptor of a packet |
check_tx_bd(num_of_bd, data); |
if ( ((data[15:0] !== 16'h7800) && (num_of_bd == 2)) || // wrap bit |
((data[15:0] !== 16'h5800) && (num_of_bd < 2)) ) // without wrap bit |
begin |
`TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]); |
test_fail("TX buffer descriptor status is not correct"); |
fail = fail + 1; |
end |
// check interrupts |
wait (wbm_working == 0); |
wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
if ((data & `ETH_INT_TXB) !== 1'b1) |
begin |
`TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data); |
test_fail("Interrupt Transmit Buffer was not set"); |
fail = fail + 1; |
end |
if ((data & (~`ETH_INT_TXB)) !== 0) |
begin |
`TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data); |
test_fail("Other interrupts (except Transmit Buffer) were set"); |
fail = fail + 1; |
end |
// clear interrupts |
wait (wbm_working == 0); |
wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// check WB INT signal |
if (wb_int !== 1'b0) |
begin |
test_fail("WB INT signal should not be set"); |
fail = fail + 1; |
end |
// INTERMEDIATE DISPLAYS |
if (num_of_bd == 0) |
$display(" ->packet with length %0d sent", (i_length + 4)); |
else if (num_of_bd == 1) |
$display(" ->packet with length %0d sent", (i_length + 4)); |
else if (num_of_bd == 2) |
$display(" ->packet with length %0d sent", (i_length + 4)); |
// set length (loop variable) |
i_length = i_length + 1; |
// the number of frame transmitted |
num_of_frames = num_of_frames + 1; |
num_of_bd = num_of_bd + 1; |
@(posedge wb_clk); |
end |
// disable TX |
wait (wbm_working == 0); |
wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN, |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
@(posedge wb_clk); |
if(fail == 0) |
test_ok; |
else |
fail = 0; |
end |
|
|
//////////////////////////////////////////////////////////////////// |
//// //// |
//// Test transmit packets across changed MAXFL value at //// |
//// 47 TX buffer decriptors ( 100Mbps ). //// |
//// //// |
//////////////////////////////////////////////////////////////////// |
if (test_num == 13) // without and with padding |
begin |
// TEST 13: TRANSMIT PACKETS ACROSS CHANGED MAXFL VALUE AT 13 TX BDs ( 100Mbps ) |
test_name = "TEST 13: TRANSMIT PACKETS ACROSS CHANGED MAXFL VALUE AT 13 TX BDs ( 100Mbps )"; |
`TIME; $display(" TEST 13: TRANSMIT PACKETS ACROSS CHANGED MAXFL VALUE AT 13 TX BDs ( 100Mbps )"); |
|
// reset MAC registers |
hard_reset; |
wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries); |
|
max_tmp = 0; |
min_tmp = 0; |
num_of_frames = 0; |
num_of_bd = 0; |
// set 47 TX buffer descriptors - must be set before TX enable |
wait (wbm_working == 0); |
wbm_write(`ETH_TX_BD_NUM, 32'h2F, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// prepare a packet of MAXFL + 10 length |
wait (wbm_working == 0); |
wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC |
min_tmp = tmp[31:16]; |
// change MAXFL value |
max_tmp = min_tmp + 53; |
wait (wbm_working == 0); |
wbm_write(`ETH_PACKETLEN, {min_tmp, max_tmp}, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
st_data = 8'h62; |
set_tx_packet(`MEMORY_BASE, max_tmp, st_data); // length with CRC |
wait (wbm_working == 0); |
wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD, |
4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// check WB INT signal |
if (wb_int !== 1'b0) |
begin |
test_fail("WB INT signal should not be set"); |
fail = fail + 1; |
end |
|
// write to phy's control register for 10Mbps |
#Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 reset - speed 100 |
#Tp eth_phy.control_bit8_0 = 9'h1_00; // bit 6 reset - (10/100), bit 8 set - FD |
speed = 100; |
|
i_length = (max_tmp - 5); // (max_tmp - 1); // not (max_tmp - 5) because NO automatic CRC appending |
while (i_length <= (max_tmp - 3)) // (max_tmp + 1)) // (max_tmp) is the limit |
begin |
wait (wbm_working == 0); |
wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY | |
`ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); |
// not detect carrier sense in FD and no collision |
eth_phy.carrier_sense_tx_fd_detect(0); |
eth_phy.collision(0); |
// first destination address on ethernet PHY |
eth_phy.set_tx_mem_addr(0); |
// prepare BDs |
if (num_of_bd == 0) |
begin |
set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, `MEMORY_BASE); |
set_tx_bd(1, 1, i_length+1, 1'b1, 1'b1, 1'b1, `MEMORY_BASE); |
set_tx_bd(2, 2, i_length+2, 1'b1, 1'b1, 1'b1, `MEMORY_BASE); |
set_tx_bd_wrap(2); |
set_tx_bd_ready(0, 0); |
end |
else if (num_of_bd == 1) |
set_tx_bd_ready(1, 1); |
else if (num_of_bd == 2) |
set_tx_bd_ready(2, 2); |
// CHECK END OF TRANSMITION |
check_tx_bd(num_of_bd, data); |
wait (MTxEn === 1'b1); // start transmit |
check_tx_bd(num_of_bd, data); |
if (data[15] !== 1) |
begin |
test_fail("Wrong buffer descriptor's ready bit read out from MAC"); |
fail = fail + 1; |
end |
wait (MTxEn === 1'b0); // end transmit |