parameter MESH_SIZE=2; // For a 2x2 mesh. parameter N_PACKETS_TO_SEND=20; // How long the test will be import mesh_defs::*; // Some common functions & definitions `include "interface.sv" // This class decides which packets to launch and when to launch them. // For now, it just launches a very simple directed test. Later we will modify // it to create a full-fledged RCG. class Sim_control; Ring_slot slots[16]; // The 16 predetermined packets we will launch. int index=0; // Index into slots[], to send them out cyclically. function new (); // We will cycle through just launching these packets. // Format is data, valid, reserved, unused, src_y, src_x, dst_y, dst_x slots[0] = '{0, 1,0,0, 0,0, 0,0}; // 0,0 -> 0,0, data=0 slots[1] = '{1, 1,0,0, 0,0, 0,1}; // 0,0 -> 0,1, data=1 slots[2] = '{2, 1,0,0, 0,0, 1,0}; // 0,0 -> 1,0, data=2 slots[3] = '{3, 1,0,0, 0,0, 1,1}; // 0,0 -> 1,1, data=3 slots[4] = '{4, 1,0,0, 0,1, 0,0}; // 0,1 -> 0,0, data=4 slots[5] = '{5, 1,0,0, 0,1, 0,1}; // 0,1 -> 0,1, data=5 slots[6] = '{6, 1,0,0, 0,1, 1,0}; // 0,1 -> 1,0, data=6 slots[7] = '{7, 1,0,0, 0,1, 1,1}; // 0,1 -> 1,1, data=7 slots[8] = '{8, 1,0,0, 1,0, 0,0}; // 1,0 -> 0,0, data=8 slots[9] = '{9, 1,0,0, 1,0, 0,1}; // 1,0 -> 0,1, data=9 slots[10] = '{10,1,0,0, 1,0, 1,0}; // 1,0 -> 1,0, data=10 slots[11] = '{11,1,0,0, 1,0, 1,1}; // 1,0 -> 1,1, data=11 slots[12] = '{12,1,0,0, 1,1, 0,0}; // 1,1 -> 0,0, data=12 slots[13] = '{13,1,0,0, 1,1, 0,1}; // 1,1 -> 0,1, data=13 slots[14] = '{14,1,0,0, 1,1, 1,0}; // 1,1 -> 1,0, data=14 slots[15] = '{15,1,0,0, 1,1, 1,1}; // 1,1 -> 1,1, data=15 endfunction : new // Launch a packet every 10 cycles. // Return the number of packets to launch *this* cycle; stuff the actual // packet (if any) into RS_array[0]. function int make_packets (ref Ring_slot RS_array[1]); int cycle; cycle = $time / 20; // Because our clock period is 20. if (cycle % 10 != 0) // Launch a new packet every 10 cycles. return (0); // So return 0 packets most of the time. RS_array[0] = slots[index % 16]; // Cycle through the 16 packet choices. index++; return (1); // Returning one packet endfunction : make_packets endclass : Sim_control // Begin the top-level module for the testbench. module automatic tb_mesh; // Declare the interface signals to the mesh. If_mesh if_mesh(); // As we launch packets, we'll save them here so we can check them later. Ring_slot packet_history [N_PACKETS_TO_SEND]; // Instantiate the top-level simulation-control object. Sim_control SC = new(); // Instantiate the NxN mesh //mesh_NxN #(.N(MESH_SIZE)) M_NxN (.*); mesh_NxN #(.N(MESH_SIZE)) M_NxN (if_mesh.DUT); // Drive the main clock and set up waveform dumping. initial begin $dumpfile("dump.vcd"); $dumpvars(); if_mesh.clk = 0; forever begin // eventually "tester" will call $stop to end the sim. #10; if_mesh.clk = ~if_mesh.clk; end end // The "tester" block, which is in charge of generating stimuli and driving // them into the DUT. // - First initialize DUT-interface signals and some of our own internals. // - Then pulse reset on for a few cycles to reset the DUT. // - Then just keep driving packets into the mesh. Don't check them -- // that's for the "mesh_checker" block. initial begin : tester int perc, good, n_bins; // For coverage stats Ring_slot RS; automatic int n_pack_sent=0, // number ever sent, so we know when to stop sending. n_pack_now=0; // number to send in the current cycle Ring_slot RS_this_cycle[1]; // to send right now // Clear the packet history before we start filling it. for (int i=0; i=N_PACKETS_TO_SEND) break; // Get new packets for this cycle, and ensure there's not too many. n_pack_now = SC.make_packets (RS_this_cycle); if (n_pack_sent+n_pack_now > N_PACKETS_TO_SEND) n_pack_now = N_PACKETS_TO_SEND-n_pack_sent; // Send the new packets for (int i=0; i