parameter MAX_PACKETS_PER_CYCLE=5; parameter MESH_SIZE=4; // For a 4x4 mesh. parameter N_PACKETS_TO_SEND=20; // How long the test will be import mesh_defs::*; // Some common functions & definitions `include "interface.sv" class AbstractPacket; // First, the stuff we need. int unsigned data; // the actual data int unsigned src_y, src_x, dst_y, dst_x; // source and dest mesh stops // Add some meta-data. For a packet we generate, it may be which initial // mesh stop to launch the packet from (and may be different from src_y, // src_x if we want to test error conditions). For a packet we receive, it // may tell us which mesh stop actually received the packet (and may be // different from dst_y,dst_x if the mesh delivered the packet to the wrong // destination). int unsigned meta_y, meta_x; bit valid; function new (input int unsigned sy=0, sx=0, dy=0, dx=0, dt=0, val=0); src_y=sy; src_x=sx; dst_y=dy; dst_x=dx; data = dt; meta_y=sy; meta_x=sx; valid=val; endfunction : new // Typically used for printing an abstract packet. // 'Print_meta' says to print the meta-data also. function string str(int print_meta=0); string s; s = $sformatf("Data=%0d, valid=%0d, from y,x=(%0d,%0d) -> (%0d,%0d)", this.data,this.valid,this.src_y,this.src_x,this.dst_y,this.dst_x); if (print_meta) s = $sformatf ("%s, Meta_y=%0d, meta_x=%0d", s,this.meta_y,this.meta_x); return (s); endfunction : str // SV doesn't natively provide a comparison on two objects of a class (other // than comparing their handles). Note we don't compare the meta-data. function equal (input AbstractPacket other); return ((this.src_y==other.src_y) && (this.src_x==other.src_x) && (this.dst_y==other.dst_y) && (this.dst_x==other.dst_x) && (this.data==other.data) && (this.valid==other.valid)); endfunction : equal endclass : AbstractPacket /* The Generator class contains all of the knobs that control our RCG. It has * various knobs to target (or not target) the destination of the packets. When * we are targeting (e.g.,) a particular row of the mesh, it remembers which * row we're targeting. When we instantiate a Sim_control, we give it all of * these knob values. * Generator is also our runtime random-packet generator. It has the smarts to * generate lots of packets, over and over, that fit the distribution that the * knobs tell it to. */ class Generator; // Get set up (i.e., pick the main mode & the main parameters) for packets for // the remainder of the test. This function gets called once at the beginning // of the test. function new (...); ... endfunction : new // This is the main external function of the Generator class. function int make_packets(ref AbstractPacket AP_array[MAX_PACKETS_PER_CYCLE]); ... endfunction : make_packets // This is the other external function of Generator. // Once the fabric has a result ready for us, (take_results_frac/10) is the // odds we take that result in any given cycle. function bit take_results(); ... endfunction : take_results endclass : Generator // We typically instantiate one Driver object, which takes an abstract packet // from the Generator and sends it into the actual physical DUT interface. class Driver; virtual If_mesh.TEST vif_mesh; function new (virtual If_mesh.TEST vif_mesh); this.vif_mesh = vif_mesh; endfunction : new // Stop sending the packets we sent last cycle. The mesh keys off our packet // having .valid=1, so we must set .valid to 0. We actually clear the entire // packet for ease of later debug. function void clear_all_mesh_inputs(); for (int y=0; y=N_PACKETS_TO_SEND) break; // Get new packets for this cycle, and ensure there's not too many. n_packets_this_cycle = GG.make_packets (AP_this_cycle); if (n_packets_sent+n_packets_this_cycle > N_PACKETS_TO_SEND) n_packets_this_cycle = N_PACKETS_TO_SEND-n_packets_sent; DD.drive_packets (AP_this_cycle, n_packets_this_cycle, n_packets_sent, packet_history); @(negedge vif_mesh.clk); end; // while not all packets sent $display ("Done launching packets at t=%0t", $time); // Stop sending the packets we sent last cycle. The mesh keys off // our packet having .valid=1, so set .valid to 0. for (int y=0; y