📄 tb_ethernet.v
字号:
`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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -