`timescale 1ns / 1ps module tb_mac_test; reg rst_n = 1'b0; reg gmii_rx_clk = 1'b0; reg gmii_tx_clk = 1'b0; reg gmii_rx_dv = 1'b0; reg [7:0] gmii_rxd = 8'h00; wire gmii_tx_en; wire [7:0] gmii_txd; wire [7:0] m_axis_rx_tdata; wire m_axis_rx_tvalid; reg m_axis_rx_tready = 1'b0; wire m_axis_rx_tlast; int cnt = 0; // ============================================================ // DUT // ============================================================ axis_mac dut ( .rst_n(rst_n), .gmii_tx_clk(gmii_tx_clk), .gmii_rx_clk(gmii_rx_clk), .gmii_rx_dv(gmii_rx_dv), .gmii_rxd(gmii_rxd), .gmii_tx_en(gmii_tx_en), .gmii_txd(gmii_txd), .m_axis_rx_tdata(m_axis_rx_tdata), .m_axis_rx_tvalid(m_axis_rx_tvalid), .m_axis_rx_tready(m_axis_rx_tready), .m_axis_rx_tlast(m_axis_rx_tlast) ); // ============================================================ // Clocks // ============================================================ always #4 gmii_rx_clk = ~gmii_rx_clk; always #4 gmii_tx_clk = ~gmii_tx_clk; // ============================================================ // Helpers // ============================================================ task automatic gmii_idle; input integer cycles; integer i; begin gmii_rx_dv <= 1'b0; gmii_rxd <= 8'h00; for (i = 0; i < cycles; i = i + 1) begin @(posedge gmii_rx_clk); end end endtask task automatic send_gmii_byte; input [7:0] b; begin @(posedge gmii_rx_clk); gmii_rx_dv <= 1'b1; gmii_rxd <= b; end endtask task automatic end_gmii_frame; begin @(posedge gmii_rx_clk); gmii_rx_dv <= 1'b0; gmii_rxd <= 8'h00; end endtask task automatic send_gmii_frame; input integer frame_len; input [8*2048-1:0] frame_data_flat; integer i; reg [7:0] current_byte; begin gmii_idle(12); for (i = 0; i < frame_len; i = i + 1) begin current_byte = frame_data_flat[i*8 +: 8]; send_gmii_byte(current_byte); end end_gmii_frame(); // inter-frame gap gmii_idle(12); end endtask reg [7:0] frame_mem [0:2047]; task automatic send_gmii_frame_mem; input integer frame_len; integer i; begin gmii_idle(12); for (i = 0; i < frame_len; i = i + 1) begin send_gmii_byte(frame_mem[i]); end end_gmii_frame(); gmii_idle(12); end endtask // ============================================================ // Monitor AXIS RX // ============================================================ always @(posedge gmii_rx_clk) begin if (m_axis_rx_tvalid && m_axis_rx_tready) begin $write("%02x ", m_axis_rx_tdata); if (m_axis_rx_tlast) $write(""); end cnt = cnt + 1; if (cnt % 8 < 6) begin m_axis_rx_tready = 1'b1; end else m_axis_rx_tready = 1'b0; end // ============================================================ // Test sequence // ============================================================ integer i; initial begin // init gmii_rx_dv = 1'b0; gmii_rxd = 8'h00; rst_n = 1'b0; gmii_idle(200); rst_n = 1'b1; gmii_idle(200); frame_mem[0] = 8'h55; frame_mem[1] = 8'h55; frame_mem[2] = 8'h55; frame_mem[3] = 8'h55; frame_mem[4] = 8'h55; frame_mem[5] = 8'h55; frame_mem[6] = 8'h55; frame_mem[7] = 8'hd5; frame_mem[8] = 8'h00; frame_mem[9] = 8'h0a; frame_mem[10] = 8'h35; frame_mem[11] = 8'h01; frame_mem[12] = 8'hfe; frame_mem[13] = 8'hc0; frame_mem[14] = 8'h30; frame_mem[15] = 8'h56; frame_mem[16] = 8'h0f; frame_mem[17] = 8'ha0; frame_mem[18] = 8'h12; frame_mem[19] = 8'hec; frame_mem[20] = 8'h08; frame_mem[21] = 8'h00; frame_mem[22] = 8'h45; frame_mem[23] = 8'h00; frame_mem[24] = 8'h00; frame_mem[25] = 8'h23; frame_mem[26] = 8'h65; frame_mem[27] = 8'hfa; frame_mem[28] = 8'h40; frame_mem[29] = 8'h00; frame_mem[30] = 8'h40; frame_mem[31] = 8'h11; frame_mem[32] = 8'h53; frame_mem[33] = 8'h7a; frame_mem[34] = 8'hc0; frame_mem[35] = 8'ha8; frame_mem[36] = 8'h00; frame_mem[37] = 8'h03; frame_mem[38] = 8'hc0; frame_mem[39] = 8'ha8; frame_mem[40] = 8'h00; frame_mem[41] = 8'h02; frame_mem[42] = 8'hc0; frame_mem[43] = 8'h31; frame_mem[44] = 8'h1f; frame_mem[45] = 8'h90; frame_mem[46] = 8'h00; frame_mem[47] = 8'h0f; frame_mem[48] = 8'he4; frame_mem[49] = 8'h7f; frame_mem[50] = 8'h6e; frame_mem[51] = 8'h65; frame_mem[52] = 8'h77; frame_mem[53] = 8'h5f; frame_mem[54] = 8'h6d; frame_mem[55] = 8'h73; frame_mem[56] = 8'h67; // FCS frame_mem[57] = 8'h00; frame_mem[58] = 8'h00; frame_mem[59] = 8'h00; frame_mem[60] = 8'h00; frame_mem[61] = 8'h00; frame_mem[62] = 8'h00; frame_mem[63] = 8'h00; frame_mem[64] = 8'h00; frame_mem[65] = 8'h00; frame_mem[66] = 8'h00; frame_mem[67] = 8'h00; frame_mem[68] = 8'h8c; frame_mem[69] = 8'ha2; frame_mem[70] = 8'h2e; frame_mem[71] = 8'h26; frame_mem[72] = 8'hdd; send_gmii_frame_mem(73); gmii_idle(200); send_gmii_frame_mem(57); gmii_idle(20); send_gmii_frame_mem(57); gmii_idle(200); send_gmii_frame_mem(66); gmii_idle(200); send_gmii_frame_mem(66); send_gmii_frame_mem(66); gmii_idle(200); $display("\nSimulation done"); $finish; end endmodule