To get current context I find caller_cx function in perlapi. But there is no description for structure. In perl source code perl.h I can find only this typedef:
typedef struct context PERL_CONTEXT;
Is there examples how to use this struct returned by caller_cx to find current package from XS?
The context struct is defined cop.h as mentioned by #Dada in the comments:
struct context {
union {
struct block cx_blk;
struct subst cx_subst;
} cx_u;
};
also the block structures are defined in cop.h.
By inspecting the C implementation of the Perl caller function in pp_ctl.c (line 1850), I think you can get the package name using the following code:
const PERL_CONTEXT *cx = caller_cx(0, NULL);
char *pack_name = HvNAME((HV*)CopSTASH(cx->blk_oldcop));
Related
I'm trying to use let-constructs instead of `define in my TB to access some signals via hierarchical paths. It's not going that great. "Normal" signals seems to work and I can access them, but typedef-signals act strange.
Here's a super simple example code that I use to trigger the error:
module dut();
// Create a type
typedef struct {
int foo;
int bar;
} ty_fooBar;
// Instantiate the type
ty_fooBar fooBar;
// Create an "alias" for fooBar
let fooBar2 = fooBar;
// Assign some values and try to access the struct members
initial begin
fooBar.foo = 3;
fooBar.bar = 7;
$display("fooBar: %p", fooBar );
$display("fooBar2: %p", fooBar2 );
$display("fooBar.fooBar: %p", fooBar.foo );
// $display("fooBar2.fooBar: %p", fooBar2.foo ); <- ERROR
end
endmodule
Simulation gives this result:
# fooBar: '{foo:3, bar:7}
# fooBar2: '{foo:3, bar:7}
# fooBar.fooBar: 3
So, fooBar should now be the same as fooBar2, ModelSim shows this with the $display command, but for some reason I can access fooBar.foo but not fooBar2.foo. I tried reading the IEEE standard but that didn't enlighten me.
What's the deal with let and typedef? Do I have some profound misunderstanding?
The let statement combines the flexibility of a `define macro with the well formed structure of function.
Like a macro. the let arguments get replaced into the body of its definition. they may be typeless.
Like a function, a let declaration is local to a scope, including a package that can be imported. References to identifiers that are not arguments are searched from the point of the declaration. And finally the problem that you are facing is that a let statement can only be called where an expression is allowed. In fact it places parenthesis around the body before substituting.
So your reference to fooBar2.foo gets expanded as (fooBar).foo which is not legal.
I'm trying to understand how typedef and enum work in SystemVerilog and, in particular, if it's possible to use a "custom" data type in a module's port declaration.
So far, I've been able to create a custom data type in a package, here it is:
typedef enum logic[2:0] {
add_conf = 3'b000,
sub_conf = 3'b001,
and_conf = 3'b010,
or_conf = 3'b011,
xor_conf = 3'b100,
sll_conf = 3'b101,
srl_conf = 3'b110,
sra_conf = 3'b111
} iexu_conf
Now, I'd like to define an input port of type iexu_conf in a module, like this:
module iexu_decoder
(
input iexu_conf conf,
output logic add_ctrl,
output logic[1:0] logic_ctrl,
output logic[1:0] shifter_ctrl,
output logic[1:0] outmux_ctrl
);
Is this possible? If so, is the syntax correct? I'm currently getting problems with Modelsim
** Error: (vlog-13069) iexu_decoder.sv(5): near "conf": syntax error, unexpected IDENTIFIER, expecting ')'.
but I can't tell if it's because of some stupid mistake or if it's due to a more serious conceptual error.
If you put the typedef in a package, you need to explicitly reference the package or import it to be visible in all module declarations that use it.
package pkg;
typedef enum logic[2:0] {
...
} iexu_conf;
endpackage
Explicit reference:
module iexu_decoder
(
input pkg::iexu_conf conf,
output logic add_ctrl,
output logic[1:0] logic_ctrl,
output logic[1:0] shifter_ctrl,
output logic[1:0] outmux_ctrl
);
Module header import:
module import pkg::*; iexu_decoder
(
input iexu_conf conf,
output logic add_ctrl,
output logic[1:0] logic_ctrl,
output logic[1:0] shifter_ctrl,
output logic[1:0] outmux_ctrl
);
I have simple c++ class as below
//example.h
#include<iostream>
class example
{
public:
int member;
void display(){
std::cout<<"Hello from example class"<<std::endl;
}
};
//my example.i file is
%module example
%{
#include "example.h"
%}
%include "example.h"
after this I am running
pkgs/swig/2.0.8/bin/swig -c++ -perl5 example.i
but I don't see a wrapper defined for my display function in .pm module thus generated.
any working sample will be of great help.
Thanks,
Harish
even though I don't see a special wrapper for display method, I see something like below generated and it worked when i was trying to access it from perl
*display = *examplec::example_display;
my code to access the c++ class objects
use example;
$myObj =new example::example();
$myObj->{member} = 1000;
print $myObj->{member};
print "\n";
$myObj->display();
print "\nFinished";
I am familiar with the collect command in Specman which returns all of the specified method's extensions. However, show source for a certain struct only returns the base struct definition and not all the extensions.
is there a command in Specman that is equivalent to collect but for structs/units?
there is no such command in Specman but since e is an incredibly flexible language you can add any command you may need using the powerful e macros.
For example, to implement what you want, you can create a macro that makes use of the reflection
Mechanism to get all layers of the desired struct and then print the relevant source lines:
define <struct_collect'command> "s_collect <any>" as {
var line_num:int;
var st:rf_struct = rf_manager.get_struct_by_name("<1>");
if (st==NULL) {
out(append("struct name does not exist : <1>"));
} else {
for each in st.as_a(rf_like_struct).get_layers() {
line_num=it.get_source_line_num();
out(append("In file ",it.get_module().get_name()," line ",line_num, " : ",files.get_text_lines(it.get_module().get_full_file_name(), line_num,line_num)));
};
};
};
you can improve on this macro, by writing the results to a file, or arrange it in a different way.
Cheers
In Python I have a flag class that I have found very useful. I'm newbe to c++, and can not seem to replicate this python functionality in c++. Rather than put up c++ code that didn't work, here's what I am looking to replicate, and I need some suggestions on where to go, templates, virtual, or ??
The requirement is being able to dynamically alter the members of the class, in python it's modifying the dict element of the class it's self that enables this.
In python:
import sys
args = []
... loads up args[] with keys:values looping through sys.argv[] ... blah blah blah
class Flag:
def __ init __(self, **args):
self. __ dict __.update(args)
now we enable flag.dynamicproperty
flag = Flag(**dict(args))
An example of use:
$ python script.py somedesc1 someval1 somedesc2 someval2
What this does is enables me to pass in parameters, as above, from the command-line and assign any number of them on-the-fly, and make then accessible by a flag.property (eg flag.somedesc1) call which returns somval1. Another way to maybe think about this is dynamically adding a key:value property to a C++ class.
An example of use in python code :
if flag.somedesc1 != '10': print someval1
I can't seem to make a comparable c++ work. I've looked into polymorphism, but these have to be assigned dynamically and then be accessible as a property of the class.
Ideas??? Surely c++ can do this, I'm just not sure where to start.
Okay, here is the solution I worked out; haven't tested it yet, but should work close enough to fit my needs using this format
flag.find(filename)
enum { filename, workers, runtime };
class flag {
vector<string> helplist;
public:
int add(int argc, char *argv[], string flag, string value, string description) {
string flagvalue;
flagvalue = value;
helplist.push_back(description);
for (int i; i < argv.length(); i++) {
if (argv[i]==flag) {
flagvalue = argv[i+1];
}
}
}
void showhelp() {
for (int i; i < helplist.length(); i++) {
cout << helplist[i] << endl;
}
}
};
No, you can't do this in C++. In C++, the members of a class are defined 100% at compile time. You cannot add any at runtime. The way to do this in C++ would be to have a member variable that's a map<string,string> that holds the key/value pairs, and then have a function string getVariable(string) that returns the value in the dictionary for that key.