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