2011年5月7日 星期六

DPI再了解(九)

Chandle data type

The chandle data type represents storage for pointers passed using the DPI
The chandle data type allows you to store a C or C++ pointer in your SystemVerilog code. A chandle variable is wide enough to hold a pointer on the machine where the code was compiled, i.e. 32- or 64-bits.

The syntax to declare a handle is as follows:
chandle variable_name ; 

where variable_name is a valid identifier. Chandles shall always be initialized to the value null, which has  a  value  of  0  on  the  C  side.  Chandles  are  restricted  in  their  usage,  with  the  only  legal  uses  being  as follows:

Only the following operators are valid on chandle variables:
—  Equality (==), inequality (!=) with another chandle or with null 
—  Case  equality  (===),  case  inequality  (!==)  with  another  chandle  or  with  null  (same semantics as == and !=)

Only the following assignments can be made to a chandle:
—     Assignment from another chandle
—     Assignment to null

Chandles can be inserted into associative arrays , but the relative ordering of any two
entries in such an associative array can vary, even between successive runs of the same tool.

Chandles can be used within a class.
—     Chandles can be passed as arguments to subroutines.
—     Chandles can be returned from functions

Chandles shall not be used as follows:
—     In any expression other than as permitted in this subclause
—     As ports
—     In sensitivity lists or event expressions
—     In continuous assignments
—     In untagged unions
—     In packed types

就是說chandle只能當作pointer, 而不能當作一般變數來用

 請參考表格

Operation C pointer SV object
handle
SV chandle
Arithmetic operations (such as incrementing)  Allowed Not Allowed Not Allowed
For arbitrary data types Allowed Not Allowed Not Allowed
Dereference when null Error Not Allowed Not Allowed
Casting Allowed Limited Not Allowed
Assignment to an address of a data type Allowed
 
Not Allowed
 
Not Allowed
 
Unreferenced objects are garbage collected No Yes No
Default value Undefined Null Null
For classes (C++) Allowed Not Allowed
 



從書上剪下的例子
#include <svdpi.h>
#include <malloc.h>
#include <veriuser.h>
typedef struct {  // Structure to hold counter value
  unsigned char cnt;
} c7;
// Construct a counter structure
void* counter7_new() {
  c7* c = (c7*) malloc(sizeof(c7));
  c->cnt = 0;
  return c;
}
// Run the counter for one cycle
void counter7(c7 *inst,
              svBitVecVal* count,
              const svBitVecVal* i,
              const svBit reset,
              const svBit load) {
  if (reset)     inst->cnt = 0;  // Reset
  else if (load) inst->cnt = *i; // Load value
  else           inst->cnt++;    // Count
  inst->cnt &= 0x7f;             // Mask upper bit
  *count = inst->cnt;            // Write to output
  io_printf("C: count=%d, i=%d, reset=%d, load=%d\n",
            *count, *i, reset, load);
}

import "DPI-C" function chandle counter7_new();
import "DPI-C" function void counter7
      (input chandle inst,
       output bit [6:0] out,
       input  bit [6:0] in,
       input  bit  reset, load);

program automatic test;
// Test two instances of the counter
  initial begin
    bit [6:0] o1, o2, i1, i2;
    bit       reset, load, clk1;
    chandle   inst1, inst2;     // Points to storage in C
    inst1 = counter7_new();
    inst2 = counter7_new();
    fork
      forever #10 clk1 = ~clk1;
      forever @(posedge clk1) begin
        counter7(inst1, o1, i1, reset, load); // 傳入所配置的記憶體位址
        counter7(inst2, o2, i2, reset, load);
      end
    join_none
    reset = 0;
    load = 0;
    i1 = 120;
    i2 = 10;
    @(negedge clk1);
    load = 1;
    @(negedge clk1);
    load = 0;
    ...
  end
endprogram

 另一個書上的例子

import "DPI-C" function chandle counter7_new();
import "DPI-C" function void counter7_count(input chandle inst);
import "DPI-C" function void counter7_load(input chandle inst,
                                           input bit [6:0] i);
import "DPI-C" function void counter7_reset(input chandle inst);
import "DPI-C" function int counter7_get(input chandle inst);
// Wrap the counter interface with a class
// to hide the C++ instance handle
class Counter7;
   chandle inst;
   function new;
      inst = counter7_new();
   endfunction
   function void count();
      counter7_count(inst);
   endfunction
   function void load(bit [6:0] val);
      counter7_load(inst, val);
   endfunction
   function void reset();
      counter7_reset(inst);
   endfunction
   function bit [6:0] get();
      return counter7_get(inst);
   endfunction
endclass : Counter7

沒有留言: