|HOME |ABOUT |ARTICLES |ACK |FEEDBACK |TOC |LINKS |BLOG |JOBS |


Tutorials



PHASE 7 RECEIVER


In this phase, we will write a receiver and use the receiver in environment class to collect the packets coming from the switch output_interface.

Receiver collects the data bytes from the interface signal. And then unpacks the bytes in to packet and pushes it into channel for score boarding.

Receiver class is written in Reveicer.sv file.


1) Extend vmm_xactor and define Receiver class.

    class Receiver extends vmm_xactor;

1) Declare a virtual output_interface. We will connect this to the Physical interface of the top module, same as what we did in environment class.

    virtual output_interface.OP output_intf;

2) Declare a channel "rcvr2sb_chan" which is used to send the packets to the score board

     Packet_channel rcvr2sb_chan;

3) Define new constructor with arguments, virtual input interface and a channel which is used to send packets from the receiver to scoreboard. Implement the restof the logic as it was done in the driver constructor.

function new(string inst = "class",
             int unsigned stream_id = -1,
             virtual output_interface.OP  output_intf_new,
             Packet_channel rcvr2sb_chan);

   super.new("Receiver",inst,stream_id);

   this.output_intf    = output_intf_new  ;

   if(rcvr2sb_chan == null)
        `vmm_fatal(log,"rcvr2sb_channel is null");
   else
        this.rcvr2sb_chan = rcvr2sb_chan;

   `vmm_note(log,"Receiver created ");

endfunction : new  


4) Define the main() method.

In start method, do the following
First call the super.main() method.
Then start a thread which collects the data from the outputinterface and then unpack the data to a packet and put into channel.

   forever
     begin
         repeat(2) @(posedge output_intf.clock);
         wait(output_intf.cb.ready)
         output_intf.cb.read <= 1;  
         repeat(2) @(posedge output_intf.clock);

         while (output_intf.cb.ready)
         begin
               bytes = new[bytes.size + 1](bytes);
               bytes[bytes.size - 1] = output_intf.cb.data_out;
              @(posedge output_intf.clock);
         end

         bytes[bytes.size - 1] = output_intf.cb.data_out;
         output_intf.cb.read <= 0;  
         @(posedge output_intf.clock);
         `vmm_note(this.log,"Received a packet ");
         pkt = new();
         pkt.byte_unpack(bytes);
         pkt.display("rcvr");

         rcvr2sb_chan.put(pkt); 

         bytes.delete();  
     end


Receiver Class Source Code:
`ifndef GUARD_RECEIVER
`define GUARD_RECEIVER

class Receiver extends vmm_xactor;

virtual output_interface.OP output_intf;
Packet_channel rcvr2sb_chan;

function new(string inst = "class",
             int unsigned stream_id = -1,
             virtual output_interface.OP  output_intf_new,
             Packet_channel rcvr2sb_chan);

   super.new("Receiver",inst,stream_id);

   this.output_intf    = output_intf_new  ;

   if(rcvr2sb_chan == null)
        `vmm_fatal(log,"rcvr2sb_channel is null");
   else
        this.rcvr2sb_chan = rcvr2sb_chan;

   `vmm_note(log,"Receiver created ");

endfunction : new  


task main();
logic [7:0] bytes[];
Packet pkt;

    super.main();
    `vmm_note(this.log," started main task ");

     forever
     begin
         repeat(2) @(posedge output_intf.clock);
         wait(output_intf.cb.ready)
         output_intf.cb.read <= 1;  
         repeat(2) @(posedge output_intf.clock);

         while (output_intf.cb.ready)
         begin
               bytes = new[bytes.size + 1](bytes);
               bytes[bytes.size - 1] = output_intf.cb.data_out;
              @(posedge output_intf.clock);
         end

         bytes[bytes.size - 1] = output_intf.cb.data_out;
         output_intf.cb.read <= 0;  
         @(posedge output_intf.clock);
         `vmm_note(this.log,"Received a packet ");
         pkt = new();
         pkt.byte_unpack(bytes);
         pkt.display("rcvr");

         rcvr2sb_chan.put(pkt); 

         bytes.delete();  
     end
endtask : main

endclass

`endif

Now we will take the instance of the receiver in the environment class.



1) Declare a channel "rcvr2sb_chan" which will be used to connect the scoreboard and receiver.

  Packet_channel rcvr2sb_chan;

2) Declare 4 receiver object "rcvr".

  Receiver rcvr[4];

3) In build method, construct the rcvr2sb_chan.

  rcvr2sb_chan = new("rcvr2sb","chan");

4) In build method, construct the receiver object. Pass the output_intf and rcvr2sb_chan. There are 4 output interfaces and receiver objects. We will connect one receiver for one output interface.

  foreach(rcvr[i])
      rcvr[i] = new($psprintf("Rcvr-%0d",i),i,output_intf[i],rcvr2sb_chan);

5) To start  the receiver activities, call the start_xactor() method of rcvr objects in the start() method of Environment class.

      rcvr[0].start_xactor();
      rcvr[1].start_xactor();
      rcvr[2].start_xactor();
      rcvr[3].start_xactor();


6) Call the stop_xactor() method of the receiver object in the stop() method of the Environment .

      rcvr[0].stop_xactor();
      rcvr[1].stop_xactor();
      rcvr[2].stop_xactor();
      rcvr[3].stop_xactor();


Environment Class Source Code:

`ifndef GUARD_ENV
`define GUARD_ENV

class Environment extends vmm_env;

  virtual mem_interface.MEM    mem_intf      ;
  virtual input_interface.IP  input_intf     ;
  virtual output_interface.OP output_intf[4] ;

  Packet_atomic_gen atomic_gen;
  Driver drvr;

  Receiver rcvr[4];

  Packet_channel gen2drvr_chan;
  Packet_channel drvr2sb_chan;

  Packet_channel rcvr2sb_chan;

function new(virtual mem_interface.MEM    mem_intf_new       ,
             virtual input_interface.IP  input_intf_new     ,
             virtual output_interface.OP output_intf_new[4] );
  super.new("Environment ");
  this.mem_intf      = mem_intf_new    ;
  this.input_intf    = input_intf_new  ;
  this.output_intf   = output_intf_new ;
  
  `vmm_note(this.log, "Created env object");
endfunction : new


  virtual function void gen_cfg();
            super.gen_cfg();
            `vmm_note(this.log,"Start of gen_cfg() method ");
            `vmm_note(this.log,"End of gen_cfg() method ");
          endfunction

  virtual function void build();
            super.build();
            `vmm_note(this.log,"Start of build() method ");
            gen2drvr_chan = new("gen2drvr","chan");
            drvr2sb_chan = new("drvr2sb","chan");

            rcvr2sb_chan = new("rcvr2sb","chan");

            atomic_gen = new("atomic_gen",0,gen2drvr_chan);
            atomic_gen.stop_after_n_insts = 10;
            drvr = new("Drvr",0,input_intf,gen2drvr_chan,drvr2sb_chan);

            foreach(rcvr[i])
            rcvr[i] = new($psprintf("Rcvr-%0d",i),i,output_intf[i],rcvr2sb_chan);

            `vmm_note(this.log,"End of build() method ");
          endfunction

  virtual task reset_dut();
            super.reset_dut();
            `vmm_note(this.log,"Start of reset_dut() method ");
              mem_intf.cb.mem_data      <= 0;
              mem_intf.cb.mem_add       <= 0;
              mem_intf.cb.mem_en        <= 0;
              mem_intf.cb.mem_rd_wr     <= 0;
              input_intf.cb.data_in     <= 0;
              input_intf.cb.data_status <= 0;
              output_intf[0].cb.read    <= 0;
              output_intf[1].cb.read    <= 0;
              output_intf[2].cb.read    <= 0;
              output_intf[3].cb.read    <= 0;
              
              // Reset the DUT
              input_intf.reset       <= 1;
              repeat (4) @ input_intf.clock;
              input_intf.reset       <= 0;

            `vmm_note(this.log,"End of reset_dut() method ");
          endtask

  virtual task cfg_dut();
            super.cfg_dut();
            `vmm_note(this.log,"Start of cfg_dut() method ");
            mem_intf.cb.mem_en <= 1;
            @(posedge mem_intf.clock);
            mem_intf.cb.mem_rd_wr <= 1;
            
            @(posedge mem_intf.clock);
            mem_intf.cb.mem_add  <= 8'h0;
            mem_intf.cb.mem_data <= `P0;
            `vmm_note(this.log ,$psprintf(" Port 0 Address %h ",`P0));
            
            @(posedge mem_intf.clock);
            mem_intf.cb.mem_add  <= 8'h1;
            mem_intf.cb.mem_data <= `P1;
            `vmm_note(this.log ,$psprintf(" Port 1 Address %h ",`P1));
            
            @(posedge mem_intf.clock);
            mem_intf.cb.mem_add  <= 8'h2;
            mem_intf.cb.mem_data <= `P2;
            `vmm_note(this.log ,$psprintf(" Port 2 Address %h ",`P2));
            
            @(posedge mem_intf.clock);
            mem_intf.cb.mem_add  <= 8'h3;
            mem_intf.cb.mem_data <= `P3;
            `vmm_note(this.log ,$psprintf(" Port 3 Address %h ",`P3));
            
            @(posedge mem_intf.clock);
            mem_intf.cb.mem_en    <=0;
            mem_intf.cb.mem_rd_wr <= 0;
            mem_intf.cb.mem_add   <= 0;
            mem_intf.cb.mem_data  <= 0;

            `vmm_note(this.log,"End of cfg_dut() method ");
          endtask

  virtual task start();
            super.start();
            `vmm_note(this.log,"Start of start() method ");
            atomic_gen.start_xactor();
            drvr.start_xactor();

            rcvr[0].start_xactor();
            rcvr[1].start_xactor();
            rcvr[2].start_xactor();
            rcvr[3].start_xactor();

            `vmm_note(this.log,"End of start() method ");
          endtask

  virtual task wait_for_end();
            super.wait_for_end();
            `vmm_note(this.log,"Start of  wait_for_end() method ");
             repeat(1000) @(input_intf.clock);
            `vmm_note(this.log,"End of  wait_for_end() method ");
          endtask

  virtual task stop();
            super.stop();
            `vmm_note(this.log,"Start of stop() method ");
            atomic_gen.stop_xactor();
            drvr.stop_xactor();

            rcvr[0].stop_xactor();
            rcvr[1].stop_xactor();
            rcvr[2].stop_xactor();
            rcvr[3].stop_xactor();

            `vmm_note(this.log,"End of stop() method ");
          endtask

  virtual task cleanup();
            super.cleanup();
            `vmm_note(this.log,"Start of cleanup() method ");
            `vmm_note(this.log,"End of cleanup() method ");
          endtask

  virtual task report();
            `vmm_note(this.log,"Start of report() method \n\n\n");
            $display("---------------------------------------------------------------------");
            super.report();
            $display("---------------------------------------------------------------------");
             $display("\n\n");
            `vmm_note(this.log,"End of report() method");
          endtask

endclass
`endif

Download the phase 7 source code:

vmm_switch_7.tar
Browse the code in vmm_switch_7.tar

Run the command:
vcs -sverilog -f filelist -R -ntb_opts rvm

Log file report.

 ******************* Start of testcase ****************
Normal[NOTE] on Environemnt() at                    0:
    Created env object
Normal[NOTE] on Environemnt() at                    0:
    Start of gen_cfg() method
Normal[NOTE] on Environemnt() at                    0:
    End of gen_cfg() method
Normal[NOTE] on Environemnt() at                    0:
    Start of build() method
Normal[NOTE] on driver(Drvr) at                    0:
    Driver created
Normal[NOTE] on Receiver(Rcvr-0) at                    0:
    Receiver created
Normal[NOTE] on Receiver(Rcvr-1) at                    0:
    Receiver created
Normal[NOTE] on Receiver(Rcvr-2) at                    0:
    Receiver created
Normal[NOTE] on Receiver(Rcvr-3) at                    0:
    Receiver created
Normal[NOTE] on Environemnt() at                    0:
    End of build() method
Normal[NOTE] on Environemnt() at                    0:
    Start of reset_dut() method
Normal[NOTE] on Environemnt() at                   60:
    End of reset_dut() method
Normal[NOTE] on Environemnt() at                   60:
    Start of cfg_dut() method
Normal[NOTE] on Environemnt() at                   90:
     Port 0 Address 00
Normal[NOTE] on Environemnt() at                  110:
     Port 1 Address 11
Normal[NOTE] on Environemnt() at                  130:
     Port 2 Address 22
Normal[NOTE] on Environemnt() at                  150:
     Port 3 Address 33
Normal[NOTE] on Environemnt() at                  170:
    End of cfg_dut() method
Normal[NOTE] on Environemnt() at                  170:
    Start of start() method
Normal[NOTE] on Environemnt() at                  170:
    End of start() method
Normal[NOTE] on Environemnt() at                  170:
    Start of  wait_for_end() method
Normal[NOTE] on driver(Drvr) at                  170:
     started main task
Normal[NOTE] on Receiver(Rcvr-0) at                  170:
     started main task
Normal[NOTE] on Receiver(Rcvr-1) at                  170:
     started main task
Normal[NOTE] on Receiver(Rcvr-2) at                  170:
     started main task
Normal[NOTE] on Receiver(Rcvr-3) at                  170:
     started main task
Normal[NOTE] on Receiver(Rcvr-0) at                  470:
    Received a packet
   rcvr   packet #0.0.0
   rcvr   da:0x00
   rcvr   sa:0xac
   rcvr   length:0x05 (data.size=4)
   rcvr   data[0]:0xcb   data[1]:0x7e   data[2]:0x52   data[3]:0xa4
   rcvr   fcs:0x29

Normal[NOTE] on Receiver(Rcvr-1) at                  710:
    Received a packet
   rcvr   packet #0.0.0
   rcvr   da:0x11
   rcvr   sa:0xf3
   rcvr   length:0x06 (data.size=5)
   rcvr   data[0]:0xc4   data[1]:0xd5  ....     data[3]:0xf3   data[4]:0x88
   rcvr   fcs:0x5b

Normal[NOTE] on Receiver(Rcvr-3) at                  890:
    Received a packet
   rcvr   packet #0.0.0
   rcvr   da:0x33
   rcvr   sa:0x6b
   rcvr   length:0x03 (data.size=2)
   rcvr   data[0]:0x32   data[1]:0x27
   rcvr   fcs:0x1c

Normal[NOTE] on Environemnt() at                10170:
    End of  wait_for_end() method
Normal[NOTE] on Environemnt() at                10170:
    Start of stop() method
Normal[NOTE] on Environemnt() at                10170:
    End of stop() method
Normal[NOTE] on Environemnt() at                10170:
    Start of cleanup() method
Normal[NOTE] on Environemnt() at                10170:
    End of cleanup() method
Normal[NOTE] on Environemnt() at                10170:
    Start of report() method
    
    
    
---------------------------------------------------------------------
Simulation PASSED on /./ (/./) at                10170 (0 warnings, 0 demoted errors & 0 demoted warnings)
---------------------------------------------------------------------



Normal[NOTE] on Environemnt() at                10170:
    End of report() method
 ******************** End of testcase *****************



Index
Introduction
Specification
Verification Plan
Phase 1 Top
Phase 2 Environment
Phase 3 Reset
Phase 4 Packet
Phase 5 Generator
Phase 6 Driver
Phase 7 Receiver
Phase 8 Scoreboard
Phase 9 Coverage

Report a Bug or Comment on This section - Your input is what keeps Testbench.in improving with time!





<< PREVIOUS PAGE

TOP

NEXT PAGE >>

copyright © 2007-2017 :: all rights reserved www.testbench.in::Disclaimer