quick.gif

space2.gif

space2.gif

space2.gif

space2.gif

space2.gif

space2.gif

space2.gif

   

space.gif

   

space.gif

  ../images/main/bullet_green_ball.gif vmm_channel

vmm_channel is like FIFO in hardware/RTL, you have one agent writing data into it and another agent reading from it as shown in figure below. Here txgen generates the transactions and pushes into vmm_channel, other end of vmm_channel is connected to bfm which waits for atleast one item in vmm_channel. Once it gets one item, it pops one item and process it. Data is written into vmm_channel needs to be of type vmm_data.

   

space.gif

../images/systemverilog/vmm_channel.png
   

space.gif

vmm_channel comes with set of methods to help use them

   

space.gif

  • size :This method returns number of elements in vmm_channel
  • is_full :This returns 1, if vmm_channel is full, but then you need to set depth of the vmm_channel
  • put :This method is blocking method, is used for pushing item into vmm_channel. If channel is full, then this method waits till atleat one item space is available
  • sneak :This method is non-blocking method, is used for pushing item into vmm_channel. It will not wait if vmm_channel is full.
  • get :This is method is blocking method, is used for poping element from vmm_channel. If channel is empty, then this method waits till atleast one item is available in vmm_channel
  • peek :This is method is non-blocking method, is used for getting one element from the vmm_channel. This method unlike get, does not delete the item from vmm_channel. Also if channel is empty, this method does not wait till one element is available. It returns null object if vmm_channel is empty
  • flush :This method is used for deleting all items in vmm_channel, can be used when you want to restart the verification enviroment for error recovery.
   

space.gif

There are other methods, which you can refer to vmm_channel class definition in vmm documentation.

   

space.gif

vmm_channel can be used with broadcase, when once channel can source to multiple sink agents. I kind of never liked it.

   

space.gif

Note :Follow below rules to avoid problems

   

space.gif

  • Always set the size of vmm_channel before using it.
  • Check type of data after get/peek with $cast
  • Try to avoid using vmm_broadcast. I personally never liked.
   

space.gif

   

space.gif

  ../images/main/bulllet_4dots_orange.gif vmm_channel Methods
   

space.gif


  1 virtual void reconfigure(int full = -1, int empty = -1, 
  2   logic fill_as_bytes = 1'bx);
  3 virtual int unsigned full_level();
  4 virtual int unsigned empty_level();
  5 virtual int unsigned level();
  6 virtual int unsigned size();
  7 virtual bit is_full();
  8 function void flush();
  9 function void sink();
 10 function void flow();
 11 function void lock(bit [1:0] who);
 12 function void unlock(bit [1:0] who);
 13 function bit is_locked(bit [1:0] who);
 14 function void display(string prefix = "");
 15 function string psdisplay(string prefix = "");
 16 task put(vmm_data obj, int offset = -1);
 17 function void sneak(vmm_data obj, int offset = -1);
 18 function vmm_data unput(int offset = -1);
 19 task get(output vmm_data obj, input int offset = 0);
 20 task peek(output vmm_data obj, input int offset = 0);
 21 task activate(output vmm_data obj, input int offset = 0);
 22 function vmm_data active_slot();
 23 function vmm_data start();
 24 function vmm_data complete(vmm_data status = null);
 25 function vmm_data remove();
 26 function active_status_e status();
 27 function bit tee_mode(bit is_on);
 28 task tee(output vmm_data obj);
 29 function void connect(vmm_channel downstream);
 30 function vmm_data for_each(bit reset = 0);
 31 function int unsigned for_each_offset();
 32 function bit record(string filename);
 33 task playback(output bit success, input string filename, 
 34   input vmm_data loader, input bit metered = 0);
You could download file vmm_channel_methods.sv here
   

space.gif

  ../images/main/bulllet_4dots_orange.gif Example : vmm_channel
   

space.gif


   1 `include "vmm.sv"
   2 
   3 // Note : This is not exact representation of AHB data class
   4 // All data class needs to extend from vmm_data
   5 class ahb_data extends vmm_data;
   6   vmm_log log;
   7   // You should use enum, when needed
   8   typedef enum {OKAY,ERROR,RETRY,SPLIT} rsp_t;
   9   typedef enum {IDLE,BUSY,NONSEQ,SEQ} tnr_t;
  10   typedef enum {WRITE,READ} cmd_t;
  11   typedef enum {SINGLE,INCR,WRAP4,INCR4,WRAP8,INCR8,WRAP16,INCR16} burst_t;
  12 
  13   // Declare all the fields
  14   rand bit [31:0] addr;
  15   rand bit [31:0] data [16];
  16   rand bit [3:0]  beats;
  17   rand tnr_t  transfer;
  18   rand rsp_t  response;
  19   rand cmd_t  cmd;
  20   rand burst_t burst;
  21 
  22   // Make sure all variables have init value 
  23   function new(vmm_log log);
  24     int i;
  25     super.new(log);
  26     this.log  = log;
  27     this.addr       = 0;
  28     for (i = 0; i < 16; i ++) begin
  29       this.data[1] = 0;
  30     end
  31     this.beats     = 0;
  32     this.transfer  = IDLE;
  33     this.response  = OKAY;
  34     this.cmd       = WRITE;
  35     this.burst     = SINGLE;
  36   endfunction
  37 
  38   // Print message
  39   function void display(string prefix = "");
  40     if (is_valid()) begin
  41      `vmm_debug(log,$psprintf("%s",psdisplay(prefix)));
  42     end else begin
  43      `vmm_error(log,$psprintf("%s",psdisplay(prefix)));
  44     end
  45   endfunction
  46 
  47   // Return the string members and their values
  48   virtual function string psdisplay(string prefix = "");
  49     string msg;
  50     int i;
  51     msg = $psprintf("   %s\n", prefix);
  52     msg = $psprintf("%s ADDRESS       : 32'h%x\n",msg,addr);
  53     msg = $psprintf("%s COMMAND       : %s\n",msg,cmd.name());
  54     msg = $psprintf("%s TRANSFER      : %s\n",msg,transfer.name());
  55     msg = $psprintf("%s RESPONSE      : %s\n",msg,response.name());
  56     msg = $psprintf("%s BEATS         : %0d\n",msg,beats);
  57     msg = $psprintf("%s BURST         : %s\n",msg,burst.name());
  58 
  59     for (i = 0; i < beats; i++) begin
  60       msg = $psprintf("%s DATA[%2d]      : 32'h%x\n",msg,i,data[i]);
  61     end
  62     psdisplay = msg;
  63   endfunction
  64 
  65   virtual function bit is_valid(bit silent = 1, int kind = -1);
  66     is_valid = (response  ! = ERROR);
  67   endfunction
  68 
  69   virtual function vmm_data copy(vmm_data to = null);
  70      ahb_data cpy;
  71      int i;
  72      if (to == null) begin
  73        cpy = new (log);
  74      end else begin
  75        if ( ! ($cast(cpy,to))) begin
  76          `vmm_fatal(log,"Passed pointer to copy method is not of type ahb_data");
  77        end
  78      end
  79     cpy.addr = this.addr;
  80     for (i = 0; i < 16; i ++) begin
  81       cpy.data[i] = this.data[1];
  82     end
  83     cpy.beats    = this.beats    ;
  84     cpy.transfer = this.transfer ;
  85     cpy.response = this.response ;
  86     cpy.cmd      = this.cmd      ;
  87     cpy.burst    = this.burst    ;
  88     copy         = cpy;
  89   endfunction
  90    
  91   virtual function bit compare( vmm_data to, output string diff, input int kind = -1);
  92     int cmp = 1;
  93     ahb_data cp;
  94     if (to == null) begin
  95       `vmm_error(log,"Passed pointer to copy method is null");
  96       return 0;
  97     end else begin
  98       if ( ! ($cast(cp,to))) begin
  99         `vmm_fatal(log,"Passed pointer to copy method is not of type ahb_data");
 100       end
 101     end
 102     if (addr  ! = cp.addr) begin
 103       diff = $psprintf("Expected 32'h%x Got 32'h%x",addr, cp.addr);
 104       return 0;
 105     end
 106     if (beats  ! = cp.beats) begin
 107       diff = $psprintf("Expected 32'h%x Got 32'h%x",beats, cp.beats);
 108       return 0;
 109     end
 110     // You can add reset of the code here
 111     compare = cmp;
 112   endfunction
 113 endclass
 114 
 115 // We need to add below line to construct vmm_channel for object ahb_data
 116 `vmm_channel(ahb_data)
 117 
 118 // This class generates transactions
 119 // Don't worry about vmm_xactor, will will see them later
 120 class source extends vmm_xactor;
 121   vmm_log log;
 122   ahb_data_channel fifo;
 123   
 124   function new(vmm_log log,string name, ahb_data_channel fifo);
 125     super.new(name, name);
 126     this.log = log;
 127     this.fifo = fifo;
 128   endfunction
 129 
 130   virtual task main();
 131     int i;
 132     ahb_data mdata;
 133     super.main();
 134      #10 ;
 135     // Generate 2 transactions
 136     for (i = 0; i < 2; i++) begin
 137       mdata = new (log);
 138       mdata.display("SOURCE"); 
 139       fifo.sneak(mdata);
 140     end
 141   endtask
 142 
 143 endclass
 144 
 145 // This class sinks transactions
 146 class sink extends vmm_xactor;
 147   ahb_data_channel fifo;
 148   vmm_log log;
 149   
 150   function new(vmm_log log, string name, ahb_data_channel fifo);
 151     super.new(name,name);
 152     this.log = log;
 153     this.fifo = fifo;
 154   endfunction
 155 
 156   virtual task main();
 157      ahb_data d;
 158      super.main();
 159      while (1) begin
 160        `vmm_note(log,$psprintf("Before Size of fifo is %0d",fifo.size()));
 161        wait_if_stopped_or_empty(fifo);
 162        `vmm_note(log,$psprintf("After Size of fifo is %0d",fifo.size()));
 163        fifo.get(d);
 164        d.display("SINK"); 
 165      end
 166   endtask
 167 endclass
 168 
 169 program test();
 170   vmm_log log = new("vmm_log_test","ahb_data");
 171   ahb_data_channel fifo = new ("CHANNEL","FIFO");
 172   source src = new(log,"SOURCE",fifo);
 173   sink   snk  = new(log,"SINK",fifo);
 174 
 175   initial begin
 176      snk.start_xactor();
 177      src.start_xactor();
 178      #1000 ;
 179   end
 180 endprogram
You could download file vmm_channel_ex.sv here
   

space.gif

  ../images/main/bulllet_4dots_orange.gif Simulation Log : vmm_channel
   

space.gif

 Trace[INTERNAL] on SOURCE(SOURCE) at                    0:
     Started
 Trace[INTERNAL] on SINK(SINK) at                    0:
     Started
 Normal[NOTE] on vmm_log_test(ahb_data) at                    0:
     Before Size of fifo is 0
 Trace[INTERNAL] on SINK(SINK) at                    0:
     1 threads have now stopped or blocked
 Debug[DEBUG] on vmm_log_test(ahb_data) at                   10:
        SOURCE
      ADDRESS       : 32'h00000000
      COMMAND       : WRITE
      TRANSFER      : IDLE
      RESPONSE      : OKAY
      BEATS         : 0
      BURST         : SINGLE
     
 Debug[INTERNAL] on CHANNEL(FIFO) at                   10:
     New instance added to channel @-1 (level 1 of 1/0)
            
      ADDRESS       : 32'h00000000
      COMMAND       : WRITE
      TRANSFER      : IDLE
      RESPONSE      : OKAY
      BEATS         : 0
      BURST         : SINGLE
     
 Debug[DEBUG] on vmm_log_test(ahb_data) at                   10:
        SOURCE
      ADDRESS       : 32'h00000000
      COMMAND       : WRITE
      TRANSFER      : IDLE
      RESPONSE      : OKAY
      BEATS         : 0
      BURST         : SINGLE
     
 Debug[INTERNAL] on CHANNEL(FIFO) at                   10:
     New instance added to channel @-1 (level 2 of 1/0)
            
      ADDRESS       : 32'h00000000
      COMMAND       : WRITE
      TRANSFER      : IDLE
      RESPONSE      : OKAY
      BEATS         : 0
      BURST         : SINGLE
     
 Debug[INTERNAL] on CHANNEL(FIFO) at                   10:
     New instance peeked from channel @0 (level 2 of 1/0)
            
      ADDRESS       : 32'h00000000
      COMMAND       : WRITE
      TRANSFER      : IDLE
      RESPONSE      : OKAY
      BEATS         : 0
      BURST         : SINGLE
     
 Normal[NOTE] on vmm_log_test(ahb_data) at                   10:
     After Size of fifo is 2
 Debug[INTERNAL] on CHANNEL(FIFO) at                   10:
     New instance removed from channel @0 (level 1 of 1/0)
            
      ADDRESS       : 32'h00000000
      COMMAND       : WRITE
      TRANSFER      : IDLE
      RESPONSE      : OKAY
      BEATS         : 0
      BURST         : SINGLE
     
 Debug[DEBUG] on vmm_log_test(ahb_data) at                   10:
        SINK
      ADDRESS       : 32'h00000000
      COMMAND       : WRITE
      TRANSFER      : IDLE
      RESPONSE      : OKAY
      BEATS         : 0
      BURST         : SINGLE
     
 Normal[NOTE] on vmm_log_test(ahb_data) at                   10:
     Before Size of fifo is 1
 Normal[NOTE] on vmm_log_test(ahb_data) at                   10:
     After Size of fifo is 1
 Debug[INTERNAL] on CHANNEL(FIFO) at                   10:
     New instance removed from channel @0 (level 0 of 1/0)
            
      ADDRESS       : 32'h00000000
      COMMAND       : WRITE
      TRANSFER      : IDLE
      RESPONSE      : OKAY
      BEATS         : 0
      BURST         : SINGLE
     
 Debug[DEBUG] on vmm_log_test(ahb_data) at                   10:
        SINK
      ADDRESS       : 32'h00000000
      COMMAND       : WRITE
      TRANSFER      : IDLE
      RESPONSE      : OKAY
      BEATS         : 0
      BURST         : SINGLE
     
 Normal[NOTE] on vmm_log_test(ahb_data) at                   10:
     Before Size of fifo is 0
 Trace[INTERNAL] on SINK(SINK) at                   10:
     1 threads have now stopped or blocked
   

space.gif

   

space.gif

   

space.gif

   

space.gif

space2.gif

space2.gif

space2.gif

space2.gif

space2.gif

  

Copyright © 1998-2014

Deepak Kumar Tala - All rights reserved

Do you have any Comment? mail me at:deepak@asic-world.com