Getting unique reference to a module passed as parameter in PACT - interface

I would like to obtain a unique key referencing a module. A unique has or the contract address would be both ok. The reason is that I want to use that string as key in a database, storing some data referenced to that token.
I am passing an interface as parameter as follows:
(defun key:string (token:module{myInterface})
; TODO
)
I've tried the hash function (hash token) but it changes on every call. Also, the describe-module function has the hash property what could be nice, but this cannot be called within a module.
I could store the hash when I load the module and pass it to the function but it is not useful because I would like to be able to call some methods in the interface.

Related

Passing Future<int> as a function pointer to C++ using dart:ffi

I want C++ code to execute a async function Future<int> inside of C++ itself as a function pointer using dart:ffi.
C++ code have to receive int value inside of C++ itself as result of Future<int>.
Also, I cannot avoid to use Future<int> because this function is provided by method channel.
Also, passing Future<int> as function pointer means that Future<int> is invoked as callback. Thus, the function which gets int from Future<int> using await is also Future<int> and it cannot be passed as function pointer.
dart:ffi accepts normal synchronous functions as function pointer.
So I tried to convert a async function Future<int> asyncFunction() async {...} to normal function int normalFunction() {...} like runBlocking {...} of Kotlin Coroutine, but I could not find any solution.
Do you have any idea to pass a async function Future<int> to C++ code as a function pointer, or evaluate Future<int> immediately and synchronously to invoke from normal function?
Simply put, you cannot pass a Future over the FFI boundary, nor is there a way in Dart to turn an async into a sync (nothing like runBlocking), but there are a few workarounds.
The simple rule for callbacks from C to Dart is that they must be called on the Dart main thread (i.e. you can only call a callback when in a C method that is being called from Dart) and must be synchronous (i.e. you cannot return a future from Dart to C).
--- Dart call through FFI to C method -->
<-- may make a callback to Dart on same thread
So, in your case, you want a Dart callback that returns an int that you can call from C (and you must only call that when handling a Dart->C call). However, you need to make a method channel call, or something else async like calling an API over HTTP.
There are a couple of workarounds, knowing that the Dart callback method must return immediately.
You can expect the callback and already have the answer ready.
You can return an invalid value, but note what was expected. Then reissue the whole request after you've got the value ready.
Real-life example
A C cryptography library needs to determine the decryption key to decrypt a file but doesn't know the key id until it reads the file header. It takes a callback that takes a string for the key id and returns the decryption key. The problem is that, in the Dart callback, we need to call an API to exchange the key id for the decryption key, and that would be async, so not allowed.
Workarounds:
In this real life example, it was actually relatively easy to read the header of the file and find the key id(s) contained in the header. (This is, of course, the first thing the C code does too.) So, before making the call to the C decrypt function, the Dart code simply read the header, ascertained the key ids, looked them up (async/await), and put the values in memory. It could then safely call the C decrypt method, knowing that the C code would discover the same key ids, and make the callback to Dart which could satisfy the key id -> key lookup from memory.
If it had not been possible to read the header in advance the second workaround is similar, but needs two bites of the cherry. Again in this example, the callback provided the key id, but had an invalid result value which meant can't find that key. On the first method invocation, the C code finds the key id, passes that to the callback which returns the invalid response, but notes the key id in memory. The C code returns a failure to decrypt error as it was not able to obtain the key. The Dart code notes the failure and further notes that it was called-back with a previously unknown key id, which it can then go and fetch (async/await again). Having fetched the key and cached it, it can retry the original method invocation. This time the callback finds the key id / key in memory, returns it and the C code is able to decrypt and return the message.
--- Dart call to C decrypt method (1st)-->
<-- C callback to Dart passing key id
--- returns not found -->
<--- C code returns unable to decrypt
Dart code looks up missing key id (async/await) and caches
--- Dart call to C decrypt method (2nd)-->
<-- C callback to Dart passing key id
--- returns cached key -->
<--- C code returns decrypted message
So, if you can predict that the C will need a particular value, have it ready in advance, before calling the C method. Or, try it, see what it asks for on the first attempt, then get it ready and try again (assuming the C will ask for the same value it asked on the first callback).

I am getting an error while trying to pass the data from scoreboard to sequence, how to get rid of it?

I am new to UVM and I am trying to verify a memory design where I am trying to run a write sequence multiple times followed by read sequence same number of times so that I could read the same addresses I am writing to, and compare. For this I tried to create a new class extended from uvm_object with a queue to store the addresses I am writing to, so that I could use them in read seq and I am instantiating this class in the scoreboard and then sending the handle of class to the read sequence via uvm_config_db, now the issue is I am able to store addresses in queue but unable to get the class handle in read sequence ......Is this the right way of checking or is there some better way to check the write and read back from memory, please help me !
entire code link (yet to complete): https://www.edaplayground.com/x/3iTr
Relevant code snippets:
This is the class I created to store the addresses
class address_list extends uvm_object;
reg[7:0]addr_q[$];
function new(string name);
super.new(name);
endfunction
endclass;
In my scoreboard, I am passing the handle of class with address queue to the read sequence, here is the snippet from scoreboard
virtual function void write(mem_seq_item pkt);
if(pkt.wr_en==1)
begin
pkt_qu_write.push_back(pkt);
addr.addr_q.push_back(pkt.addr);
uvm_config_db#(address_list)::set(uvm_root::get(),"*","address",addr);
end
if(pkt.rd_en==1)
pkt_qu_read.push_back(pkt);
`uvm_info(get_type_name(),$sformatf("Adder list is
%p",addr.addr_q),UVM_LOW)
endfunction : write
In my read sequence, I am trying to get the handle
virtual task body();
repeat(3)
`uvm_do(wr_seq)
if(!uvm_config_db#(address_list)::get(this, " ", "address", addr_))
`uvm_fatal("NO_VIF",{"virtual interface must be set for:",get_full_name(),".addr_"});
`uvm_info(get_type_name(),$sformatf("ADDR IS %p",addr_),UVM_LOW)
repeat(3)
`uvm_do(rd_seq)
endtask
Error-[ICTTFC] Incompatible complex type usage
mem_sequence.sv, 137 {line where i try to get from uvm_config_db}
Incompatible complex type usage in task or function call.
The following expression is incompatible with the formal parameter of the
function. The type of the actual is 'class $unit::wr_rd_sequence', while
the
type of the formal is 'class uvm_pkg::uvm_component'. Expression: this
Source info: uvm_config_db#
(_vcs_unit__3308544630::address_list)::get(this,
" ", "address", this.addr_)
There are two problems with this line:
if(!uvm_config_db#(address_list)::get(this, " ", "address", addr_))
One is causing your error. One might lead to you not being able to find what you're looking for in the database.
This (literally this) is causing your error. You are calling get from a class derived from uvm_sequence. The first argument to get is expecting a class derived from uvm_component. Your problem is that a sequence is not part of the testbench hierarchy, so you cannot use a sequence as the first argument to a call to get (or set) in a uvm_config_db. Instead the convention is to use the sequencer that the sequence is running on, which is returned by a call to the sequence's get_sequencer() method. This solves your problem:
if(!uvm_config_db#(address_list)::get(get_sequencer(), "", "address", addr_))
This works because you used a wildcard when you called set.
Notice that I also removed the space from between the quotes. That might not give you a problem, because you used the wildcard when you called set, but in general this string should either be empty or should be a real hierarchical path. (The hierarchy input to the set and get calls is split between the first argument - a SystemVerilog hierarchical path - and the second - a string representing a hierarchical path).
uvm_config_db is basically for passing configuration between components.
For purpose of passing data from scoreboard to sequence, you can use uvm_event.
Trigger event in scoreboard using event.trigger(address_list)
sequence wait for event using event.wait_for_trigger_data(address_list)

Edit `TABLE-HANDLER` to point to another temp-table

I'm trying to overwrite the parameter handler, so it'd point to another temp-table with different schema.
myProcedure.p
DEFINE TEMP-TABLE TT_RealTable NO-UNDO
BEFORE-TABLE TT_RealTableBefore
FIELD name AS CHAR
.
DEF INPUT-OUTPUT PARAM TABLE-HANDLE TH_NewTable.
CREATE TT_RealTable.
ASSIGN TT_RealTable.name = "Ben".
CREATE TT_RealTable.
ASSIGN TT_RealTable.name = "Harry".
The TH_NewTable points to a random parameter TEMP-TABLE with different schema and contents. I want to overwrite this parameter TABLE-HANDLER with the TT_RealTable. If I try to set:
TH_NewTable = TEMP-TABLE TT_RealTable:HANDLE.
The program will crash at runtime saying that TT_RealTable's schema/meta data doesn't match the handler's one.
How I can overwrite the handler to point to my TT_RealTable:HANDLE, and return it as output?
If the schema IS different as the error claims, and you said at the beginning of your post, what you want to do can't be done. You can't pass a temp-table buffer handle that has a certain definition and return something else at the end of the procedure, assuming the parameter table handle is from a static temp-table. Even if it isn't, you'd need to create the temp-table using the buffer handle AFTER calling the procedure, which I'm thinking is not what you want, since your parameter is input-output.
If you really want to work with a table that's fluid as far as schema goes, you should read into dynamic temp-tables. Look for the CREATE TEMP-TABLE statement in help and read through the examples to understand how you can get a handle and then (and only then) build a temp-table using the returned handle, so you can use that. You lose the ability of using regular statements, though, such as create and assign. You'll have to reference BUFFER-FIELD and BUFFER-VALUE, and use the CREATE method instead, using the buffer-handle. Might take a while to get used to it, but it's not rocket science.
Hope it helps!

Prevent automatic hash function for mutable classes

Python allows hash values only for immutable objects. For example,
hash((1,2,3))
works, but
hash([1,2,3])
raises a TypeError: unhashable type: 'list'. See the Python documentation. However, when I wrap a C++ class in Boost.Python via the usual boost::python::class_<> function, every generated Python class has a default hash function, where the hash value is related to the object's location in memory. (On my 64-bit OS, the hash value is the location divided by 8.)
When I expose a class to Python whose members can be changed (any mutable data structure, so this is a very common situation!), I do not want a default hash function but want a call to hash() raise the same TypeError as users receive for Python's own mutable data types. In particular, users shouldn't be able to accidentally use mutable objects as dictionary keys. How can I achieve this in the C++ code?
I found out how it goes:
boost::python::class_<MyClass>("MyClass")
.setattr("__hash__", boost::python::object());
A boost::python::object which is initialized with no arguments corresponds to None. The procedure for disabling hash generation in the pure Python C API is a little more complicated, as is described in the Python documentation. However, the above code snippet apparently does the job in boost::python.
On a sidenote: The Boost.Python behaviour mirrors the default behaviour of classes in Python, where objects are basically hashable as of object id (derived from id(x)):
>>> hash(object())
8795488122377
>>> class MyClass(object): pass
...
>>> hash(MyClass)
878579
>>> hash(MyClass())
8795488082665
>>>

How to share data between ExtJS grids

I am working with a PERL Miner::Base and JavaScript platform (.pm and .js).
My JavaScript contains 3 ExtJS GridPanels.
Now, here's my problem:
I have a function that takes ~1 minute to run and returns a list with references to the data needed for all 3 grids. Let's call this function "foo".
Currently, in order to load each of my grids' store, I call a function that calls "foo" and returns only the relevant reference out of the list returned by "foo".
I need a way to call "foo" only once and share the data it returns between my 3 stores.
Is there such a way?
Thanks.
Here is the basic structure of my code:
my_code.js:
gridA with storeA (calls my_code.pm::get_A_data)
gridB with storeB (calls my_code.pm::get_B_data)
gridC with storeC (calls my_code.pm::get_C_data)
my_code.pm:
get_A_data (calls foo and returns the first reference returned from foo)
get_B_data (calls foo and returns the second reference returned from foo)
get_C_data (calls foo and returns the third reference returned from foo)
If you have three grids you effectively would need to have three stores. However you can do one request, get a store object and then clone it into other two local copies. Search for cloning ExtJs store