My current project sets an environment variable in a perl module and then later on makes a call from a SystemVerilog file to a function that uses that variable. The requirement is that whatever we added in the perl module is present in the environment variable on time of the call.
The problem however is that something between the perl module and systemverilog call meddles with my variable. I can't figure out what it is and fixing this issue is not pertinent to my project so I just want to set the variable to whatever the perl module sets it to and move on.
There's a handy getenv function in Perl and I am able to use getenv in SV as well. But there doesn't seem to be a setenv. What is the appropriate way to set an environment variable in SV?
Is the perl code invoked from within SystemVerilog using a $system() call? If so, environment changes made by the perl code will definitely NOT propagate back to the SV world, because those changes are made only in the $system() subprocess's environment.
The setenv() system call works for me via SystemVerilog DPI-C in all the tools I use (recent Fedora OS, recent versions of Mentor/Cadence/Synopsys simulators), but there may be some older *nix systems on which it's not available. I used the prototype as given in "man 3 setenv". Looking at discussions on other StackOverflow forums, it seems that using putenv() is not a great idea, especially from the DPI where you have no idea what will happen to the memory used for the DPI string argument. setenv() makes a copy of its argument strings, and should not be at risk from that problem.
It seems to me that if your tool flow isn't correctly propagating environment variables in the way you intend, then you have bigger problems than how to mess with the env from SystemVerilog. I specifically chose NOT to add environment-modifying functions to the svlib utility library, precisely because using the environment is a very bad way to communicate information within a SV simulation. I guess it would make sense if you need to set up an environment for some external program that you would then invoke using a SV $system() call.
Mh... Turns out the answer is trivial but this is the only thread to this question so I'll leave it up in case someone else finds themselve in a similar situation:
SystemVerilog does not have a setenv( ) or getenv( ) function. They're actually implemented from C using the following construct:
module/program foo();
import "DPI-C" function <return type> foonction(<function arguments>);
endmodule/program;
Apparently in my case someone had done this for getenv( ) but never setenv ( ). Reason I didn't catch it was because my code in question was included the following way:
**foo.sv**
if(var.bit) begin
call_function();
use_environment_variable();
end
**bar.sv**
module bar();
<do stuff>
`include foo.sv <-- foo code is copied in after calculations have occured.
endmodule
Trying to import DPI-C in foo.sv will trigger an error because the import will arrive after calculations have taken place. To solve this we need to import in bar.sv like so:
module bar();
import "DPI-C" function int setenv(string name, string value, int override);
<do stuff>
`include foo.sv
endmodule
Setting environment variables from SV is not very useful unless you are running another executable from SV.
If you want to get environment variables, you can use Verilab's svlib functions:
function automatic string sys_getEnv(string envVar);
function automatic bit sys_hasEnv(string envVar);
Related
As much as I can (mostly for clarity/documentation), I've been trying to say
use Some::Module;
use Another::Module qw( some namespaces );
in my Perl modules that use other modules.
I've been cleaning up some old code and see some places where I reference modules in my code without ever having used them:
my $example = Yet::Another::Module->AFunction($data); # EXAMPLE 1
my $demo = Whats::The::Difference::Here($data); # EXAMPLE 2
So my questions are:
Is there a performance impact (I'm thinking compile time) by not stating use x and simply referencing it in the code?
I assume that I shouldn't use modules that aren't utilized in the code - I'm telling the compiler to compile code that is unnecessary.
What's the difference between calling functions in example 1's style versus example 2's style?
I would say that this falls firmly into the category of preemptive optimisation and if you're not sure, then leave it in. You would have to be including some vast unused libraries if removing them helped at all
It is typical of Perl to hide a complex issue behind a simple mechanism that will generally do what you mean without too much thought
The simple mechanisms are these
use My::Module 'function' is the same as writing
BEGIN {
require My::Module;
My::Module->import( 'function' );
}
The first time perl successfully executes a require statement, it adds an element to the global %INC hash which has the "pathified" module name (in this case, My/Module.pm) for a key and the absolute location where it found the source as a value
If another require for the same module is encountered (that is, it already exists in the %INC hash) then require does nothing
So your question
What happens if I reference a package but don't use/require it?
We're going to have a problem with use, utilise, include and reference here, so I'm code-quoting only use and require when I mean the Perl language words.
Keeping things simple, these are the three possibilities
As above, if require is seen more than once for the same module source, then it is ignored after the first time. The only overhead is checking to see whether there is a corresponding element in %INC
Clearly, if you use source files that aren't needed then you are doing unnecessary compilation. But Perl is damn fast, and you will be able to shave only fractions of a second from the build time unless you have a program that uses enormous libraries and looks like use Catalyst; print "Hello, world!\n";
We know what happens if you make method calls to a class library that has never been compiled. We get
Can't locate object method "new" via package "My::Class" (perhaps you forgot to load "My::Class"?)
If you're using a function library, then what matters is the part of use that says
My::Module->import( 'function' );
because the first part is require and we already know that require never does anything twice. Calling import is usually a simple function call, and you would be saving nothing significant by avoiding it
What is perhaps less obvious is that big modules that include multiple subsidiaries. For instance, if I write just
use LWP::UserAgent;
then it knows what it is likely to need, and these modules will also be compiled
Carp
Config
Exporter
Exporter::Heavy
Fcntl
HTTP::Date
HTTP::Headers
HTTP::Message
HTTP::Request
HTTP::Response
HTTP::Status
LWP
LWP::MemberMixin
LWP::Protocol
LWP::UserAgent
Storable
Time::Local
URI
URI::Escape
and that's ignoring the pragmas!
Did you ever feel like you were kicking your heels, waiting for an LWP program to compile?
I would say that, in the interests of keeping your Perl code clear and tidy, it may be an idea to remove unnecessary modules from the compilation phase. But don't agonise over it, and benchmark your build times before doing any pre-handover tidy. No one will thank you for reducing the build time by 20ms and then causing them hours of work because you removed a non-obvious requirement.
You actually have a bunch of questions.
Is there a performance impact (thinking compile time) by not stating use x and simply referencing it in the code?
No, there is no performance impact, because you can't do that. Every namespace you are using in a working program gets defined somewhere. Either you used or required it earlier to where it's called, or one of your dependencies did, or another way1 was used to make Perl aware of it
Perl keeps track of those things in symbol tables. They hold all the knowledge about namespaces and variable names. So if your Some::Module is not in the referenced symbol table, Perl will complain.
I assume that I shouldn't use modules that aren't utilized in the code - I'm telling the compiler to compile code that is unnecessary.
There is no question here. But yes, you should not do that.
It's hard to say if this is a performance impact. If you have a large Catalyst application that just runs and runs for months it doesn't really matter. Startup cost is usually not relevant in that case. But if this is a cronjob that runs every minute and processes a huge pile of data, then an additional module might well be a performance impact.
That's actually also a reason why all use and require statements should be at the top. So it's easy to find them if you need to add or remove some.
What's the difference between calling functions in example 1's style versus example 2's style?
Those are for different purposes mostly.
my $example = Yet::Another::Module->AFunction($data); # EXAMPLE 1
This syntax is very similar to the following:
my $e = Yet::Another::Module::AFunction('Yet::Another::Module', $data)
It's used for class methods in OOP. The most well-known one would be new, as in Foo->new. It passes the thing in front of the -> to the function named AFunction in the package of the thing on the left (either if it's blessed, or if it's an identifier) as the first argument. But it does more. Because it's a method call, it also takes inheritance into account.
package Yet::Another::Module;
use parent 'A::First::Module';
1;
package A::First::Module;
sub AFunction { ... }
In this case, your example would also call AFunction because it's inherited from A::First::Module. In addition to the symbol table referenced above, it uses #ISA to keep track of who inherits from whom. See perlobj for more details.
my $demo = Whats::The:Difference::Here($data); # EXAMPLE 2
This has a syntax error. There is a : missing after The.
my $demo = Whats::The::Difference::Here($data); # EXAMPLE 2
This is a function call. It calls the function Here in the package Whats::The::Difference and passes $data and nothing else.
Note that as Borodin points out in a comment, your function names are very atypical and confusing. Usually functions in Perl are written with all lowercase and with underscores _ instead of camel case. So AFunction should be a_function, and Here should be here.
1) for example, you can have multiple package definitions in one file, which you should not normally do, or you could assign stuff into a namespace directly with syntax like *Some::Namespace::frobnicate = sub {...}. There are other ways, but that's a bit out of scope for this answer.
Python is my newest language (Python-2.6), my background is in C/C++. Normally, I would create a global variable and be able to modify and access it across all of my files. I am trying to achieve that same functionality in python.
Based off of this post: Python - Visibility of global variables in imported modules I see that "Globals in Python are global to a module, not across all modules". I have multiple variables that rely on user input, and must be accessed and modified by four different modules and in the main code, which is why I am trying to use global(ish) variables in Python.
I have two attemps to make this work:
1) If I stick the code with the modifiable global variables in my main code, I run into the issue of "Executing the Main Module Twice" as detailed here: http://python-notes.curiousefficiency.org/en/latest/python_concepts/import_traps.html The program works, other than being executed twice.
2) If I create a separate module and put the variables into a function, I find that I have undefined variables in my other modules and my code will error out. From steping through the code, I see that when the variables are accessible/modifiable by moduleA, but then everything breaks when moduleB and moduleC try to use them, because the modifications did not stay.
How do I utilize Python to suit my needs? I believe my problem lies with attempting to use global variables and importing the global variables
To solve this issue, I stopped trying to use global variables across multiple modules in my main code and stopped importing individual variables. I basically ended up placing moduleA(a single function) within moduleB. I created a class within moduleB for the functions I needed. The main code and moduleC now accesses those functions.
I still use global variables though, within the functions in moduleB. If I made the variables not global I got attribute errors.
In some CPAN modules I found the next construction
BEGIN {
$Package::Name::VERSION = "N.N";
}
What is a rationale behind putting the package version information into the BEGIN block?
for example: http://cpansearch.perl.org/src/JSWARTZ/Poet-0.12/lib/Poet/Cache.pm
EDIT - in the most recent module version it is pulled out, but anyway - it was here - so wondering why it is good (or bad) :)
It's one of those things that everyone has always done and can't remember why!
Essentially it is because use statements allow multiple modules to be in compilation at the same time, so although it looks like a module is complete it may have only just started compiling.
Any code being compiled can check the value of $Module::VERSION by using the inherited UNIVERSAL::VERSION subroutine, which is already defined implicitly before a module even starts compiling.
Remember that, if Module.pm contains
use Another::Module;
Then compilation of Module.pm is put on hold while Another/Module.pm is compiled.
There is nothing to stop Another::Module from doing
use Module 1.5;
which will call Module::VERSION(1.5) (inherited from UNIVERSAL::VERSION) to check that $Module::VERSION is 1.5 or greater.
If $Module::VERSION is defined outside a BEGIN block, it won't be set until after all use statements have been completed, and so too late for other modules to do version checking on Module.
I hope this is clear. I can't help thinking there must be a simpler explanation, but nothing comes to mind.
How can I perform a "shallow" syntax check on perl files. The standard perl -c is useful but it checks the syntax of imports. This is sometimes nice but not great when you work in a code repository and push to a running environment and you have a function defined in the repository but not yet pushed to the running environment. It fails checking a function because the imports reference system paths (ie. use Custom::Project::Lib qw(foo bar baz)).
It can't practically be done, because imports have the ability to influence the parsing of the code that follows. For example use strict makes it so that barewords aren't parsed as strings (and changes the rules for how variable names can be used), use constant causes constant subs to be defined, and use Try::Tiny changes the parse of expressions involving try, catch, or finally (by giving them & prototypes). More generally, any module that exports anything into the caller's namespace can influence parsing because the perl parser resolves ambiguity in different ways when a name refers to an existing subroutine than when it doesn't.
There are two problems with this:
How to not fail -c if the required modules are missing?
There are two solutions:
A. Add a fake/stub module in production
B. In all your modules, use a special catch-all #INC subroutine entry (using subs in #INC is explained here). This obviously has a problem of having the module NOT fail in real production runtime if the libraries are missing - DoublePlusNotGood in my book.
Even if you could somehow skip failing on missing modules, you would STILL fail on any use of the identifiers imported from the missing module or used explicitly from that module's namespace.
The only realistic solution to this is to go back to #1a and use a fake stub module, but this time one that has a declared and (as needed) exported identifier for every public interface. E.g. do-nothing subs or dummy variables.
However, even that will fail for some advanced modules that dynamically determine what to create in their own namespace and what to export in runtime (and the caller code could dynamically determine which subs to call - heck, sometimes which modules to import).
But this approach would work just fine for normal "Java/C-like" OO or procedural code that only calls statically named predefined public subs, methods and accesses exported variables.
I would suggest that it's better to include your code repository in your syntax check. perl -I/path/to/working/code/repo/local_perl/ -c or set PERL5LIB=/path/to/working/code/repo/local_perl/ prior to running perl -c. Either option should allow you to check against your working code, assuming you have it in a directory structure similar to your live code.
I guess you could make stubs for the missing libraries in your home folder.
Have you looked into PPI? I think it does follow imports, however it could perhaps be more easily modified to guess what looks like a function name.
Do you use
require "name"
or
local name = require "name"
Also, do you explicitly declare system modules as local variables? E.g.
local io = require "io"
Please explain your choice.
Programming in Lua 2ed says "if she prefers to use a shorter name for a module, she can set a local name for it" and nothing about local m = require "mod" being faster than require "mod". If there's no difference I'd rather use the cleaner require "mod" declaration and wouldn't bother writing declarations for pre-loaded system modules.
Either of them works. Storing it in a local will not change the fact that the module may have registered global functions.
Some libraries work only one way, and some only work the other way
The require "name" syntax was the one introduced in lua 5.1; as a note; this call does not always return the module; but it was expected a global would be created with the name of the library (so, you now have a _G.name to use the library with). eg, earlier versions of gsl-if you did local draw = require"draw" the local draw would contain true; and shadow the global draw created by the library.
The behaviour above is encouraged by the module function ==> now relatively deprecated, any well written new code will not use it.
The local name = require"name" syntax became preferred recently (about 2008?); when it was decided that modules setting any globals for you was a bad thing.
As a point: all my libraries do not set globals, and just return a table of functions; or in some other cases, they return an function that works as an initialiser for the root object.
tldr;
In new code, you should use the latter local name = require"name" syntax; it works in the vast majority of cases, but if you're working with some older modules, they may not support it, and you'll have to just use require"module".
To answer your added question:
do you require the system modules?: no; you just assume they are already required; but I do localise all functions I use (usually grouped into lines by the module they came from), including those from external libraries. This allows you to easily see which functions your code actually relies on; as well as removing all GETGLOBALs from your bytecode.
Edit: localising functions is now discouraged. To find accidental globals use a linter like luacheck
Sample module in (my) preferred style; will only work with the local name = require"name" syntax.
local my_lib = require"my_lib"
local function foo()
print("foo")
end
local function bar()
print("bar", my_lib.new())
end
return {
foo = foo;
bar = bar;
}
I would say it mainly boils down to what you prefer, but there are some exceptions depending on what you are writing. Creating a local reference will gain you some speed, but in most cases this isn't a meaningful optimization to do. You should also point your local to the function you are using and not the module table.
If you are writing on a library then I would recommend creating local references for all the global variables you use. Even if you aren’t using the module() function, which changes the global scope for the code that follows. The reason for this is that it prevents your library from calling globals which have been altered after the library was loaded.
Doing local io = require’io’ will ensure you that you get the table from package.loaded.io, even if _G.io has been replaced by another table. I generally don’t do this myself. I expect io to already be loaded and unmodified when I write Lua.
You also have to remember that there are several ways to write a Lua module. Some modules don't return their module table, while others don't create any global variable. The most common solution is to both create and return a global, but you can't always rely on this.