Modelsim / reading a signal value - vhdl

In my simulation, I want to have RW access to signals whereever there are in the project. To get the write access, I use the "signal_force" procedure from the modelsim_lib library. But to get the read access I havn't find the corresponding function.
The reason why signal_force fit my needs is that I'm working with input text files, so I have the name and the value of the signal from a "string" or a "line" variable and I can directly give these variable to the fonction.
I cannot use the "init_signal_spy" procedure because this procedure doesn't give back a value into a string but just duplicates the behavior of a signal onto an other. As my project has to be as generic as possible, I work with variables declared into procedures and I cannot link a signal onto a variable.
Thanks for your help

edited
Sorry, I win the "did not read very carefully" award for the day...
Just for completeness, I'm leaving the part of my answer that deals with signal spy (which is a proprietary ModelSim method), even though you said it wouldn't work for you:
library modelsim_lib;
use modelsim_lib.util.all;
architecture ...
signal local_sig ...
begin
process
begin
init_signal_spy("/sim/path/to/signal/internal_sig", "local_sig");
With VHDL-2008 (if you have support for it), the standard way to access signals not in scope is hierarchical/external names, and as a bonus, it does both "write" and "read". I may be a bit rusty on the nuances, but you access them like:
<<signal .sim.path.to.signal.internal_sig : std_logic>>
And you should be able to use that in place of any normal in-scope identifier, I believe. Aliases, assignments, etc.

If you're comfortable writing C code it should be straightforward to achieve what you want using the VHPI, although sadly despite being part of the VHDL standard Mentor are not planning to implement it. However it will also be possible using FLI although you're locked into a proprietary interface.
Something like this:
procedure get_signal_value_as_string(
vhdl_path : IN string;
vhdl_value: OUT string);
attribute FOREIGN of get_signal_value_as_string : procedure is “my_func mylib.so”;
procedure get_signal_value_as_string(
vhdl_path : IN string;
vhdl_value: OUT string) is
begin
report “ERROR: foreign subprogram get_signal_value_as_string not called”;
end;
Then in C:
#include <stdio.h>
#include "mti.h"
/* Convert a VHDL String array into a NULL terminated string */
static char *get_string(mtiVariableIdT id)
{
static char buf[1000];
mtiTypeIdT type;
int len;
mti_GetArrayVarValue(id, buf);
type = mti_GetVarType(id);
len = mti_TickLength(type);
buf[len] = 0;
return buf;
}
void my_func (
mtiVariableIdT vhdl_path /* IN string */
mtiVariableIdT vhdl_value /* OUT string */
)
{
mtiSignalIdT sigID = mti_FindSignal(get_string(vhdl_path));
mtiInt32T value = mti_GetSignalValue(sigID);
...
}
Plenty of example code in the FLI manual.

Related

Returning a string from a Function (VAX PASCAL)

This is one for the software archaeologists!
And before you ask why was I even bothering to try to get this to work the reason it is simply because I can - which I think is a perfectly good excuse!
I found that the following code for a procedure compiles using VAX PASCAL (and runs as expected)..
PROCEDURE format(number : INTEGER);
VAR
result : STRING(16);
BEGIN
:
:
writeln(result);
END.
However if turn this into a function and try to return the result as a string it won't compile.
FUNCTION format(number : INTEGER) : STRING(16);
VAR
result : STRING(16);
BEGIN
:
:
format := result;
END.
The error suggests that the error is at type definition for the function.
FUNCTION format(number : INTEGER) : STRING(16);
1
PASCAL-E-TYPCNTDISCR, Type can not be discriminated in this context
I tried using VARYING and ARRAY types instead of STRING but they don't work either. Unfortunately I can't find an example of a function that returns a STRING in SYS$EXAMPLES or in the manuals I found of bitsavers.
Hopefully someone has a better memory than me.
Thanks
"Pascal's type system has been described as "too strong", because the size of an array or string is part of its type, ..." Strong and weak typing
This gives a hint that the String(16) in the function return value is too vague for the compiler.
Fix that by declaring a string type that suits the compiler:
type
String16 = packed array[1..16] of char;
Then you can use that distinct type in the function:
FUNCTION format(number : INTEGER) : String16;
VAR
result : String16;
BEGIN
:
:
format := result;
END.
This is very much what was used in many early implementations of the pascal language (and Turbo Pascal), and is still valid. Modern compilers, like Delphi and FreePascal, has implemented a specialized dynamic array for strings, which covers a more convenient handling of the string type, not depending on declaring a strict size.

External Procedure memory allocations

I have some existing functions written in C that take pointers to two arrays and do some calculations on the data. I wanted to call those functions from PL/SQL as external procedures. Our data is stored in Oracle as a BLOB. So, I made a wrapper shared object to be called from PL/SQL. It felt like overkill to pass the BLOB into every wrapper function and parse it into these two arrays with every single external procedure call. So, instead I made a function called ParseBlobToArrays
which looks like:
int OracleBlobToDataArrays(OCIExtProcContext* ctx,OCILobLocator* blob,
//some other stuff I can't post used to parse blob,
unsigned int* address1, unsigned int* address2)
{
//this isn't all the code, error checking etc here as well
unsigned char* buf = OCIExtProcAllocCallMemory(ctx,lobLen ))
//read blob into allocated buf
double* arr1 = ParseToArray1(buf,//some additional params);
float** arr2 = ParseToArray2(buf,//some additional params);
*address1= (unsigned int)((uintptr_t) arr1);
*address2= (unsigned int)((uintptr_t) arr2);
}
I then return the addresses and feed them into each subsequent function that needs them and set them appropriately:
double OtherFunctionWrapper(unsigned int address1,unsigned int address2)
{
double* arr1 = (double*)address1;
float** arr2 = (float**)address2;
return DoCalculation(arr1,arr2);;
}
I then call a Free wrapper function I wrote which takes the addresses, casts again to appropriate types and then frees all the pointers.
There is a code smell I don't like:
The C code is passing memory addresses like this when PL/SQL doesn't seem to support a uintptr_t/64 bit binary integer (or even exposing these raw addresses at all). Casting and returning the address as a UINT32 and then moving this to 64 bit OS in the future would potentially blow up I believe, if the address doesn't fit in a UINT32.
I could parse the data into arrays and return them to PL/SQL as OCIColls, but then I need to use OCI specific data types etc. This is safer (I think?), but I already have the BLOB parsed and in memory to be used. Seems silly to pass data back to PL/SQL as PL/SQL supported types just to be passed in to other functions, when all I really need is a pointer to data that already exists in the format I want in memory.
Any advice on handling this differently? If the right option is to do everything with supported PL/SQL datatypes and return them accordingly, I will. But I am looking for other options as well to minimize duplicate code with each call to various calculation functions since speed of these external procedures is very important.
Thanks!

Why use extra procedure to initialize values instead of doing it in constructor?

So i've been going trough types at my new work and they pretty much all look like this
create or replace TYPE BODY T_Some_Type AS
CONSTRUCTOR FUNCTION T_Some_Type
RETURN SELF AS RESULT AS
BEGIN
INTIALIZE();
RETURN;
END T_Some_Type;
MEMBER PROCEDURE INTIALIZE AS
BEGIN
var1 := 0;
var2 := 0;
var3 := 0;
END INTIALIZE;
END;
Being skilled in OOP but new to pl/sql, i keep wondering why use extra procedure to initialize variables, when it can be done directly in constructor making objects interface simpler and lighter on memory.
This is how i would normally do it :
create or replace TYPE BODY T_Some_Type AS
CONSTRUCTOR FUNCTION T_Some_Type
RETURN SELF AS RESULT AS
BEGIN
var1 := 0;
var2 := 0;
var3 := 0;
RETURN;
END T_Some_Type;
END;
Is there any advantage or this is recommended for some reason?
Please advise.
Please bear in mind that the object features in Oracle have evolved slowly since version 8.0, and yet are still pretty limited in some respects. This is because Oracle is a relational database with a structured and procedural programming paradigm: object-orientation is not a good fit.
So. In a language like Java we can override a method in a sub-type but execute the code in the parent's implementation with a super() call.
Before 11g Oracle had no similar mechanism for extending member functions. If we wanted to override a super-type's method we had to duplicate the code in the sub-type, which was pretty naff. There was a workaround which is not much less naff: extract the common code into a separate method in the super-type, and call that method in the super- type and its dependents.
In 11g Oracle introduced "Generalized Invocation". This allows us to call super-type code on a sub-type. Find out more. There is one major limitation with Generalized Invocation, and that is that we cannot use it with Constructor methods. Therefore, in its sub-types' constructors too our only choice is to put that code in a method like the initialize() in your question.

Add a mathematical operation to standard TCL ones

As you know TCL has some mathematical functions such as sin, cos, and hypot that are called in expr command with () braces as follows:
puts [expr sin(1.57)]
Now how can I add a function using TCL library functions so that it was called exactly the same way, and was doing something that a certain proc defines.
I would like to clarify my question. Say there is a proc (string) as follows:
proc add { a b } { return [expr $a+$b] } ;# string of a proc
Also I have a TCL interpreter in my C++ code. Now I want get the string of a proc and runtime register a function called add into the tcl::mathfunc namespace (I guess I should use Tcl_CreateObjCommand) so that I could call the following:
puts [expr add(1.57, 1.43)]
How this can be done. Could you please write a simple example. I could not find any example in TCL documentation and in books as well which describe the usage of this command.
Creating a function from C isn't too hard. To do it, you've got to write an implementation of a command that will perform the operation, and register that implementation as a command in the correct namespace. (In 8.4 and before, functions were done with a separate interface that was quite a bit nastier to use; the mechanism was wholly overhauled in 8.5.)
Command Implementation
Note that the signature is defined, and the ignored parameter is not used here. (It's really a void * — great when you're wanting to do things like binding a command to an object — but it simply isn't needed for doing an addition.)
static int AddCmd(ClientData ignored, Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]) {
double x, y, sum;
/* First, check number of arguments: command name is objv[0] always */
if (objc != 3) {
Tcl_WrongNumArgs(interp, 1, objv, "x y");
return TCL_ERROR;
}
/* Get our arguments as doubles */
if ( Tcl_GetDoubleFromObj(interp, objv[1], &x) != TCL_OK ||
Tcl_GetDoubleFromObj(interp, objv[2], &y) != TCL_OK) {
return TCL_ERROR;
}
/* Do the real operation */
sum = x + y;
/* Pass the result out */
Tcl_SetObjResult(interp, Tcl_NewDoubleObj(sum));
return TCL_OK;
}
Don't worry about the fact that it's allocating a value here; Tcl's got a very high performance custom memory manager that makes that a cheap operation.
Command Registration
This is done usually inside an initialization function that is registered as part of a Tcl package definition or which is called as part of initialization of the overall application. You can also do it directly if you are calling Tcl_CreateInterp manually. Which you do depends on how exactly how you are integrating with Tcl, and that's quite a large topic of its own. So I'll show how to create an initialization function; that's usually a good start in all scenarios.
int Add_Init(Tcl_Interp *interp) {
/* Use the fully-qualified name */
Tcl_CreateObjCommand(interp, "::tcl::mathfunc::add", AddCmd, NULL, NULL);
return TCL_OK;
}
The first NULL is the value that gets passed through as the first (ClientData) parameter to the implementation. The second is a callback to dispose of the ClientData (or NULL if it needs no action, as here).
Doing all this from C++ is also quite practical, but remember that Tcl is a C library, so they have to be functions (not methods, not without an adapter) and they need C linkage.
To get the body of a procedure from C (or C++), by far the easiest mechanism is to use Tcl_Eval to run a simple script to run info body theCmdName. Procedure implementations are very complex indeed, so the interface to them is purely at the script level (unless you actually entangle yourself far more with Tcl than is really wise).

Delphi Interface Performance Issue

I have done some really serious refactoring of my text editor. Now there is much less code, and it is much easier to extend the component. I made rather heavy use of OO design, such as abstract classes and interfaces. However, I have noticed a few losses when it comes to performance. The issue is about reading a very large array of records. It is fast when everything happens inside the same object, but slow when done via an interface. I have made the tinyest program to illustrate the details:
unit Unit3;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
const
N = 10000000;
type
TRecord = record
Val1, Val2, Val3, Val4: integer;
end;
TArrayOfRecord = array of TRecord;
IMyInterface = interface
['{C0070757-2376-4A5B-AA4D-CA7EB058501A}']
function GetArray: TArrayOfRecord;
property Arr: TArrayOfRecord read GetArray;
end;
TMyObject = class(TComponent, IMyInterface)
protected
FArr: TArrayOfRecord;
public
procedure InitArr;
function GetArray: TArrayOfRecord;
end;
TForm3 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form3: TForm3;
MyObject: TMyObject;
implementation
{$R *.dfm}
procedure TForm3.FormCreate(Sender: TObject);
var
i: Integer;
v1, v2, f: Int64;
MyInterface: IMyInterface;
begin
MyObject := TMyObject.Create(Self);
try
MyObject.InitArr;
if not MyObject.GetInterface(IMyInterface, MyInterface) then
raise Exception.Create('Note to self: Typo in the code');
QueryPerformanceCounter(v1);
// APPROACH 1: NO INTERFACE (FAST!)
// for i := 0 to high(MyObject.FArr) do
// if (MyObject.FArr[i].Val1 < MyObject.FArr[i].Val2) or
// (MyObject.FArr[i].Val3 < MyObject.FArr[i].Val4) then
// Tag := MyObject.FArr[i].Val1 + MyObject.FArr[i].Val2 - MyObject.FArr[i].Val3
// + MyObject.FArr[i].Val4;
// END OF APPROACH 1
// APPROACH 2: WITH INTERFACE (SLOW!)
for i := 0 to high(MyInterface.Arr) do
if (MyInterface.Arr[i].Val1 < MyInterface.Arr[i].Val2) or
(MyInterface.Arr[i].Val3 < MyInterface.Arr[i].Val4) then
Tag := MyInterface.Arr[i].Val1 + MyInterface.Arr[i].Val2 - MyInterface.Arr[i].Val3
+ MyInterface.Arr[i].Val4;
// END OF APPROACH 2
QueryPerformanceCounter(v2);
QueryPerformanceFrequency(f);
ShowMessage(FloatToStr((v2-v1) / f));
finally
MyInterface := nil;
MyObject.Free;
end;
end;
{ TMyObject }
function TMyObject.GetArray: TArrayOfRecord;
begin
result := FArr;
end;
procedure TMyObject.InitArr;
var
i: Integer;
begin
SetLength(FArr, N);
for i := 0 to N - 1 do
with FArr[i] do
begin
Val1 := Random(high(integer));
Val2 := Random(high(integer));
Val3 := Random(high(integer));
Val4 := Random(high(integer));
end;
end;
end.
When I read the data directly, I get times like 0.14 seconds. But when I go through the interface, it takes 1.06 seconds.
Is there no way to achieve the same performance as before with this new design?
I should mention that I tried to set PArrayOfRecord = ^TArrayOfRecord and redefined IMyInterface.arr: PArrayOfRecord and wrote Arr^ etc in the for loop. This helped a lot; I then got 0.22 seconds. But it is still not good enough. And what makes it so slow to begin with?
Simply assign the array to a local variable before iterating through the elements.
What you're seeing is that the interface methods calls are virtual and have to be called through an indirection. Also, the code has to pass-through a "thunk" that fixes up the "Self" reference to now point to the object instance and not the interface instance.
By making only one virtual method call to get the dynamic array, you can eliminate that overhead from the loop. Now your loop can go through the array items without the extra overhead of the virtual interface method calls.
You're comparing oranges with apples, as the first test reads a field (FArr), while the second test reads a property (Arr) that has a getter assigned with it. Alas, interfaces offer no direct access to their fields, so you really can't do it any other way than like you did.
But as Allen said, this causes a call to the getter method (GetArray), which is classified as 'virtual' without you even writing that because it's part of an interface.
Thus, every access results in a VMT-lookup (indirected via the interface) and a method call.
Also, the fact that you're using a dynamic array means that both the caller and the callee will do a lot of reference-counting (you can see this if you take a look at the generated assembly code).
All this is already enough reasons to explain the measured speed difference, but can indeed easily be overcome using a local variable and read the array only once. When you do that, the call to the getter (and all the ensueing reference counting) is taking place only once. Compared to the rest of the test, this 'overhead' becomes unmeasurable.
But note, that once you go this route, you'll loose encapsulation and any change to the contents of the array will NOT reflect back into the interface, as arrays have copy-on-write behaviour. Just a warning.
Patrick and Allen's answers are both perfectly correct.
However, since your question talks about improved OO design, I feel a particular change in your design that would also improve performance is appropriate to discuss.
Your code to set the Tag is "very controlling". What I mean by this is that you're spending a lot of time "poking around inside another object" (via an interface) in order to calculate your Tag value. This is actually what exposed the "performance problem with interfaces".
Yes, you can simply deference the interface once to a local variable, and get a massive improvement in performance, but you'll still be poking around inside another object. One of the important goals in OO design is to not poke around where you don't belong. This actually violates the Law of Demeter.
Consider the following change which empowers the interface to do more work.
IMyInterface = interface
['{C0070757-2376-4A5B-AA4D-CA7EB058501A}']
function GetArray: TArrayOfRecord;
function GetTagValue: Integer; //<-- Add and implement this
property Arr: TArrayOfRecord read GetArray;
end;
function TMyObject.GetTagValue: Integer;
var
I: Integer;
begin
for i := 0 to High(FArr) do
if (FArr[i].Val1 < FArr[i].Val2) or
(FArr[i].Val3 < FArr[i].Val4) then
begin
Result := FArr[i].Val1 + FArr[i].Val2 -
FArr[i].Val3 + FArr[i].Val4;
end;
end;
Then inside TForm3.FormCreate, //APPROACH 3 becomes:
Tag := MyInterface.GetTagValue;
This will be as fast as Allen's suggestion, and will be a better design.
Yes, I'm fully aware you simply whipped up a quick example to illustrate the performance overhead of repeatedly looking something up via interface. But the point is that if you have code performing sub-optimally because of excessive accesses via interfaces - then you have a code smell that suggests you should consider moving the responsibility for certain work into a different class. In your example TForm3 was highly inappropriate considering everything required for the calculation belonged to TMyObject.
your design use huge memory. Optimize your interface.
IMyInterface = interface
['{C0070757-2376-4A5B-AA4D-CA7EB058501A}']
function GetCount:Integer:
function GetRecord(const Index:Integer):TRecord;
property Record[Index:Integer]:TRecord read GetRecord;
end;

Resources