|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

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

Receiver class is written in Reveicer.sv file.

Receiver class is defined by extending ovm_component class. It will drive the received transaction to scoreboard using ovm_analysis_port.



1) Define Receiver class by extending ovm_component.

`ifndef GUARD_RECEIVER
`define GUARD_RECEIVER

class Receiver extends ovm_component;

endclass : Receiver

`endif

2) Declare configuration class object.

    Configuration cfg;

3) Declare an integer to hold the receiver number.

    integer id;

4) Declare a virtual interface of dut out put side.

  virtual output_interface.OP output_intf;

5) Declare analysis port which is used by receiver to send the received transaction to scoreboard.

  ovm_analysis_port #(Packet) Rcvr2Sb_port;

6) Declare the utility macro. This utility macro provides the implementation of creat() and get_type_name() methods.

  `ovm_component_utils(Receiver) 

7) Define the constructor.

   function new (string name, ovm_component parent);
      super.new(name, parent);
   endfunction : new

8) Define the build method and construct the Rcvr2Sb_port.

   function void build();
      super.build();
      Rcvr2Sb_port = new("Rcvr2Sb", this); 
   endfunction : build

9) In the end_of_elaboration() method, get the configuration object using get_config_object and update the virtual interfaces.

   function void end_of_elaboration();
      ovm_object tmp;
      super.end_of_elaboration();
      assert(get_config_object("Configuration",tmp));
      $cast(cfg,tmp);
      output_intf = cfg.output_intf[id]; 
   endfunction : end_of_elaboration

10) Define the run() method. This method collects the packets from the DUT output interface and unpacks it into high level transaction using transactions unpack_bytes() method.

    virtual task run();
     bit [7:0] bytes[];
     Packet pkt;

         fork
         forever
         begin
             repeat(2) @(posedge output_intf.clock);
             wait(output_intf.ready)
             output_intf.read <= 1;  
    
             repeat(2) @(posedge output_intf.clock);
             while (output_intf.ready)
             begin
                   bytes = new[bytes.size + 1](bytes);
                   bytes[bytes.size - 1] = output_intf.data_out;
                  @(posedge output_intf.clock);
             end

             output_intf.read <= 0;  
             @(posedge output_intf.clock);
             ovm_report_info(get_full_name(),"Received packet ...",OVM_LOW);
             pkt = new();
             pkt.unpack_bytes(bytes);
             Rcvr2Sb_port.write(pkt);
             bytes.delete();  
         end
         join

     endtask : run



Receiver class source code
`ifndef GUARD_RECEIVER
`define GUARD_RECEIVER

class Receiver extends ovm_component;

    virtual output_interface.OP output_intf;

    Configuration cfg;

    integer id;

    ovm_analysis_port #(Packet) Rcvr2Sb_port;

   `ovm_component_utils(Receiver) 

    function new (string name, ovm_component parent);
        super.new(name, parent);
    endfunction : new


    function void build();
        super.build();
        Rcvr2Sb_port = new("Rcvr2Sb", this);
    endfunction : build

    function void end_of_elaboration();
        ovm_object tmp;
        super.end_of_elaboration();
        assert(get_config_object("Configuration",tmp));
        $cast(cfg,tmp);
        output_intf = cfg.output_intf[id]; 
    endfunction : end_of_elaboration

     virtual task run();
     bit [7:0] bytes[];
     Packet pkt;

         fork
         forever
         begin
             repeat(2) @(posedge output_intf.clock);
             wait(output_intf.ready)
             output_intf.read <= 1;  
    
             repeat(2) @(posedge output_intf.clock);
             while (output_intf.ready)
             begin
                   bytes = new[bytes.size + 1](bytes);
                   bytes[bytes.size - 1] = output_intf.data_out;
                  @(posedge output_intf.clock);
             end

             output_intf.read <= 0;  
             @(posedge output_intf.clock);
             ovm_report_info(get_full_name(),"Received packet ...",OVM_LOW);
             pkt = new();
             pkt.unpack_bytes(bytes);
             Rcvr2Sb_port.write(pkt);
             bytes.delete();  
         end
         join

     endtask : run

endclass :  Receiver

Environment Class Updates

We will update the Environment class and take instance of receiver and run the testcase.



1) Declare 4 receivers.

    Receiver Rcvr[4];

2) In the build() method construct the Receivers using create() methods. Also update the id variable of the receiver object.  

    foreach(Rcvr[i]) begin
        Rcvr[i]   = Receiver::type_id::create($psprintf("Rcvr%0d",i),this);
        Rcvr[i].id = i;
    end

Environment class source code

`ifndef GUARD_ENV
`define GUARD_ENV

class Environment extends ovm_env;

    `ovm_component_utils(Environment)

     Sequencer Seqncr;
     Driver Drvr;

     Receiver Rcvr[4];

    function new(string name , ovm_component parent = null);
        super.new(name, parent);
    endfunction: new

    function void build();
        super.build();
        ovm_report_info(get_full_name(),"START of build ",OVM_LOW);
        Drvr   = Driver::type_id::create("Drvr",this);
        Seqncr = Sequencer::type_id::create("Seqncr",this);

        foreach(Rcvr[i]) begin
            Rcvr[i]   = Receiver::type_id::create($psprintf("Rcvr%0d",i),this);
            Rcvr[i].id = i;
        end

        ovm_report_info(get_full_name(),"END of build ",OVM_LOW);
    endfunction
    
    function void connect();
        super.connect();
        ovm_report_info(get_full_name(),"START of connect ",OVM_LOW);
        Drvr.seq_item_port.connect(Seqncr.seq_item_export);
        ovm_report_info(get_full_name(),"END of connect ",OVM_LOW);
    endfunction

endclass : Environment
`endif

Download the Source Code

ovm_switch_7.tar
Browse the code in ovm_switch_7.tar

Command to run the simulation

 vcs -sverilog +incdir+$OVM_HOME/src $OVM_HOME/src/ovm_pkg.sv +incdir+. rtl.sv interface.sv top.sv -R +OVM_TESTNAME=test1
 qverilog +incdir+$OVM_HOME/src $OVM_HOME/src/ovm_pkg.sv +incdir+. rtl.sv interface.sv top.sv -R +OVM_TESTNAME=test1


Log report after simulation

OVM_INFO @ 0 [RNTST] Running test test1...
OVM_INFO @ 0: ovm_test_top.t_env [ovm_test_top.t_env] START of build
OVM_INFO @ 0: ovm_test_top.t_env [ovm_test_top.t_env] END of build
OVM_INFO @ 0: ovm_test_top.t_env [ovm_test_top.t_env] START of connect
OVM_INFO @ 0: ovm_test_top.t_env [ovm_test_top.t_env] END of connect
----------------------------------------------------------------------
Name                     Type                Size                Value
----------------------------------------------------------------------
Seqncr                   Sequencer           -               Seqncr@14
--rsp_export             ovm_analysis_export -           rsp_export@16
--seq_item_export        ovm_seq_item_pull_+ -      seq_item_export@40
--default_sequence       string              19    ovm_random_sequence
--count                  integral            32                     -1
--max_random_count       integral            32                   'd10
--sequences              array               5                       -
----[0]                  string              19    ovm_random_sequence
----[1]                  string              23   ovm_exhaustive_sequ+
----[2]                  string              19    ovm_simple_sequence
----[3]                  string              23   Seq_device0_and_dev+
----[4]                  string              19    Seq_constant_length
--max_random_depth       integral            32                    'd4
--num_last_reqs          integral            32                    'd1
--num_last_rsps          integral            32                    'd1
----------------------------------------------------------------------
OVM_INFO @ 30: ovm_test_top.t_env.Drvr [ovm_test_top.t_env.Drvr]
               Start of reset_dut() method
OVM_INFO @ 70: ovm_test_top.t_env.Drvr [ovm_test_top.t_env.Drvr]
               End of reset_dut() method
OVM_INFO @ 70: ovm_test_top.t_env.Drvr [ovm_test_top.t_env.Drvr]
               Start of cfg_dut() method
OVM_INFO @ 110: ovm_test_top.t_env.Drvr [ovm_test_top.t_env.Drvr]
               Port 0 Address 00
OVM_INFO @ 130: ovm_test_top.t_env.Drvr [ovm_test_top.t_env.Drvr]  
               Port 1 Address 01
OVM_INFO @ 150: ovm_test_top.t_env.Drvr [ovm_test_top.t_env.Drvr]
               Port 2 Address 02
OVM_INFO @ 170: ovm_test_top.t_env.Drvr [ovm_test_top.t_env.Drvr]
               Port 3 Address 03
OVM_INFO @ 190: ovm_test_top.t_env.Drvr [ovm_test_top.t_env.Drvr]
               End of cfg_dut() method
OVM_INFO @ 210: ovm_test_top.t_env.Drvr [ovm_test_top.t_env.Drvr]
               Driving packet ...
OVM_INFO @ 590: ovm_test_top.t_env.Drvr [ovm_test_top.t_env.Drvr]
               Driving packet ...
OVM_INFO @ 610: ovm_test_top.t_env.Rcvr0 [ovm_test_top.t_env.Rcvr0]
               Received packet ...
OVM_INFO @ 970: ovm_test_top.t_env.Drvr [ovm_test_top.t_env.Drvr]
               Driving packet ...
OVM_INFO @ 990: ovm_test_top.t_env.Rcvr0 [ovm_test_top.t_env.Rcvr0]
               Received packet ...

--- OVM Report Summary ---

** Report counts by severity
OVM_INFO :   18
OVM_WARNING :    0
OVM_ERROR :    0
OVM_FATAL :    0


Index
Introduction
Specification
Verification Plan
Phase 1 Top
Phase 2 Configuration
Phase 3 Environment N Testcase
Phase 4 Packet
Phase 5 Sequencer N Sequence
Phase 6 Driver
Phase 7 Receiver
Phase 8 Scoreboard

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