How to remove the ports from my include files from my file using Verilog::SigParser - perl

I'm using Verilog package in Perl, so I can read a Verilog file and extract the ports the are inside. For this purpose, I'm using Verilog::SigParser, if you are new here you should know that Verilog::SigParser provide callbacks for when a signal is declared, a module instantiated or a module defined. The file you are passing is obviously a Verilog file. The problem here is I I'm trying to use SigParser in a file which includes inside another file (just it's name, not its content, scroll down for better understanding), and it looks like ports from the include file are getting inside my %arr(), which later on gives me some mistakes because of course I can't form the testbench. So let me show you some code:
This is my perl file:
#On top of the file
package MyParser
use Verilog::SigParser
$filename = /user/home/verilog.v
....
use base qw(Verilog::SigParser);
my %arr = (); #In this array, all module inputs and outputs are being saved.
#Process my verilog file
my $vf Verilog::Preproc->new(keep_comments->0);
$vf->open(filename=>$filename) or die $!;
open(FH,'>',/users/home/port_file);
print(FH, %arr()); #HERE IT IS INCLUDING NOT JUST THE PORTS FROM VERILOG.V BUT ALSO THE ONES FROM HAPPY.VP, I want only the ones from verilog.v
close(FH);
Top file verilog.v
`include happy.vp
module top();
.
#lots of inputs and outputs
.
.
endmodule
File happy.vp
module happy();
#some other inputs or outputs I don't want in my ports file.
endmodule

A SystemVerilog package cannot access any date type or data item declared outside of the scope of that package except via import from another previously compiled package. There is no way to import from a compilation unit.
typedef int t; // outside space is part of some compilation unit
package p;
t v; // reference to t is illegal
endpackage

Related

How to fix Verilog::VCD::Writer error: Can't locate object method addSignal?

I suspect I made an import error in Perl.
There is a Perl module Verilog::VCD::Writer to write a VCD file. However, when I copy its SYNOPSIS code to have a try, it always raises the error:
Can't locate object method "addSignal" via package
"Verilog::VCD::Writer" at tester.pl line 10.
The SYNOPSIS calls addComment and addModule before addSignal so there should be no problems in my installation.
addSignal is a function defined in Verilog/VCD/Writer/Module.pm, and the other two are defined in Verilog/VCD/Writer.pm. Even I add Verilog::VCD::Writer::Module, still the debugger go to package Writer to find the addSignal method.
If I call the addSignal function in this way:
$writer->Verilog::VCD::Writer::Module::addSignal("TX",7,0);
Can't locate object method "signals_push" via package
"Verilog::VCD::Writer" at
/home/cqsun/lib/perl5/lib/site_perl/5.18.2/Verilog/VCD/Writer/Module.pm
line 41.
Module.pm defined signals_push in a hash, and clearly the debugger didn't find it.
I suspect there is something wrong, but I don't know where it is.
The webpage for this package is http://search.cpan.org/~jvs/Verilog-VCD-Writer-0.002/lib/Verilog/VCD/Writer.pm
This is a documentation bug.
The code in the SYNOPSIS section of the POD has a few problems. The error you see is from the line:
my $TX=$writer->addSignal("TX",7,0); #Add Signals to top
The code used the wrong object handle for the addSignal method. $writer is an object of the Verilog::VCD::Writer module, and it does not have an addSignal method. However, addSignal is a method of the Verilog::VCD::Writer::Module module. The code needs to use $top instead of $writer.
The next line has the same problem:
my $RX=$writer->addSignal("RX",7,0);
Finally, the following line has a syntax error because it is missing the comment delimiter (#) after the semicolon:
my $dut=$top->addModule("DUT"); Create SubModule
Here is a fixed version of the code which runs without errors and generates a VCD output file:
use Verilog::VCD::Writer;
my $writer = Verilog::VCD::Writer->new(timescale=>'1 ns',vcdfile=>"test.vcd");
$writer->addComment("Author:Vijayvithal");
my $top = $writer->addModule("top"); # Create toplevel module
my $TX = $top->addSignal("TX",7,0); #Add Signals to top
my $RX = $top->addSignal("RX",7,0);
my $dut = $writer->addModule("DUT"); #Create SubModule
$dut->dupSignal($TX,"TX",7,0); #Duplicate signals from Top in submodule
$dut->dupSignal($RX,"RX",7,0);
$writer->writeHeaders(); # Output the VCD Header.
$writer->setTime(0); # Time 0
$writer->addValue($TX,0); # Record Transition
$writer->addValue($RX,0);
$writer->setTime(5); # Time 1ns
$writer->addValue($TX,1);
$writer->addValue($RX,0);
I uploaded a patch to the bug report you opened:
https://rt.cpan.org/Ticket/Display.html?id=123724
Also, the Create SubModule comment seems misleading. Perhaps the author intended to use the addSubModule method instead of the addModule method.

Python w/QT Creator form - Possible to grab multiple values?

I'm surprised to not find a previous question about this, but I did give an honest try before posting.
I've created a ui with Qt Creator which contains quite a few QtWidgets of type QLineEdit, QTextEdit, and QCheckbox. I've used pyuic5 to convert to a .py file for use in a small python app. I've successfully got the form connected and working, but this is my first time using python with forms.
I'm searching to see if there is a built-in function or object that would allow me to pull the ObjectNames and Values of all widgets contained within the GUI form and store them in a dictionary with associated keys:values, because I need to send off the information for post-processing.
I guess something like this would work manually:
...
dict = []
dict['checkboxName1'] = self.checkboxName1.isChecked()
dict['checkboxName2'] = self.checkboxName2.isChecked()
dict['checkboxName3'] = self.checkboxName3.isChecked()
dict['checkboxName4'] = self.checkboxName4.isChecked()
dict['lineEditName1'] = self.lineEditName1.text()
... and on and on
But is there a way to grab all the objects and loop through them, even if each different type (i.e. checkboxes, lineedits, etc) needs to be done separately?
I hope I've explained that clearly.
Thank you.
Finally got it working. Couldn't find a python specific example anywhere, so through trial and error this worked perfectly. I'm including the entire working code of a .py file that can generate a list of all QCheckBox objectNames on a properly referenced form.
I named my form main_form.ui from within Qt Creator. I then converted it into a .py file with pyuic5
pyuic5 main_form.ui -o main_form.py
This is the contents of a sandbox.py file:
from PyQt5 import QtCore, QtGui, QtWidgets
import sys
import main_form
# the name of my Qt Creator .ui form converted to main_form.py with pyuic5
# pyuic5 original_form_name_in_creator.ui -o main_form.py
class MainApp(QtWidgets.QMainWindow, main_form.Ui_MainWindow):
def __init__(self):
super(self.__class__, self).__init__()
self.setupUi(self)
# Push button object on main_form named btn_test
self.btn_test.clicked.connect(self.runTest)
def runTest(self):
# I believe this creates a List of all QCheckBox objects on entire UI page
c = self.findChildren(QtWidgets.QCheckBox)
# This is just to show how to access objectName property as an example
for box in c:
print(box.objectName())
def main():
app = QtWidgets.QApplication(sys.argv) # A new instance of QApplication
form = MainApp() # We set the form to be our ExampleApp (design)
form.show() # Show the form
app.exec_() # and execute the app
if __name__ == '__main__': # if we're running file directly and not importing it
main() # run the main function
See QObject::findChildren()
In C++ the template argument would allow one to specify which type of widget to retrieve, e.g. to just retrieve the QLineEdit objects, but I don't know if or how that is mapped into Python.
Might need to retrieve all types and then switch handling while iterating over the resulting list.

Using a variable in a library name when trying to use a library perl

I want my library name to change (I have reasons), but when I use a variable in the library path, it can't seem to find it.....Can't locate APOE.pm in #INC
my ($plugin_name) = #ARGV;
use lib("/usr/share/perl/5.10.1/$plugin_name");
use APOE qw(callAPOE);
Is this not possible?
Edit:
$plugin_name = "AIB-TorrentPanel-v2.00";
AND module name is
APOE.pm
You could simply write:
use lib "/usr/share/perl/5.10.1/$ARGV[0]";
or, if you need to do something more complicated to set up the directory name than your example code shows:
my $plugin_name;
BEGIN {
($plugin_name) = #ARGV;
}
use lib "/usr/share/perl/5.10.1/$plugin_name";
Your my ($plugin_name) = #ARGV; will run at run-time, it is too late for lib. According to the manual of lib, use lib LIST; is almost equals
BEGIN { unshift(#INC, LIST) }
but your $plugin_name would not be available at that time.
However, you could replace your use with a require, like this:
my ($plugin_name) = #ARGV;
require "/usr/share/perl/5.10.1/$plugin_name/APOE.pm";

Accessing subs from a require'd perl script

I'm going to import some perl code with the require statement. The code I'd like to import is in mylibA.pl:
#!/usr/bin/perl
package FOO::BAR;
sub routine {
print "A message!\n";
}
and mylibB.pl:
#!/usr/bin/perl
package FOO::BAZ;
sub routine {
print "Another message!\n";
}
Then I'm going to use it like this:
#!/usr/bin/perl
foreach my $lib (qw/ mylibA.pl mylibB.pl /){
require $lib;
print "Make a call to ${lib}'s &routine!\n";
}
Is there a way for my script to figure out the namespace that was pulled in with the require statement?
Wow. I have to say this is the one of the most interesting Perl questions I've seen in a while. On the surface this seems like a very simple request - get an included module's namespace, but there really is no way to do this. You can get it while in the package, but not from outside the package. I tried using EXPORT to send the local package name back to the caller script but that ended up going nowhere given the difference in how "use" and "require" work. A more module type of approach probably would have worked with a "use" statement, but the requirement that the required script be able to run by themselves prevented that approach. The only thing left to do was to directly pollute the caller's namespace and hope for the best (assume that the caller had no package namespace) - something that modules are designed to prevent.
BTW - I can't believe this actually works - in strict mode, no less.
caller.pl
#!/usr/bin/perl
use strict;
#package SomePackageName; #if you enable this then this will fail to work
our $ExportedPackageName;
print "Current package=".__PACKAGE__."\n";
foreach my $lib (qw/ mylibA.pl mylibB.pl /){
require $lib;
print "Make a call to ${lib}'s &routine!\n";
print "Package name exported=".$ExportedPackageName."\n";
$ExportedPackageName->routine;
} #end foreach
print "Normal Exit";
exit;
__END__
mylibA.pl
#!/usr/bin/perl
package FOO::BAR;
use strict;
#better hope the caller does not have a package namespace
$main::ExportedPackageName=__PACKAGE__;
sub routine {
print "A message from ".__PACKAGE__."!\n";
}
1;
mylibB.pl
#!/usr/bin/perl
package FOO::BAZ;
use strict;
#better hope the caller does not have a package namespace
$main::ExportedPackageName=__PACKAGE__;
sub routine {
print "Another message, this time from ".__PACKAGE__."!\n";
}
1;
Result:
c:\Perl>
c:\Perl>perl caller.pl
Current package=main
Make a call to mylibA.pl's &routine!
Package name exported=FOO::BAR
A message from FOO::BAR!
Make a call to mylibB.pl's &routine!
Package name exported=FOO::BAZ
Another message, this time from FOO::BAZ!
Normal Exit
Regarding the mostly academical problem of finding the package(s) in a perl source file:
You can try the CPAN module Module::Extract::Namespaces to get all packages within a perl file. It is using PPI and is thus not 100% perfect, but most of the time good enough:
perl -MModule::Extract::Namespaces -e 'warn join ",", Module::Extract::Namespaces->from_file(shift)' /path/to/foo.pm
But PPI can be slow for large files.
You can try to compare the active packages before and after the require. This is also not perfect, because if your perl library file loads additional modules then you cannot tell which is the package of the prinicipal file and what's loaded later. To get the list of packages you can use for example Devel::Symdump. Here's a sample script:
use Devel::Symdump;
my %before = map { ($_,1) } Devel::Symdump->rnew->packages;
require "/path/to/foo.pm";
my %after = map { ($_,1) } Devel::Symdump->rnew->packages;
delete $after{$_} for keys %before;
print join(",", keys %after), "\n";
You can also just parse the perl file for "package" declarations. Actually, that's what the PAUSE upload daemon is doing, so it's probably "good enough" for most cases. Look at the subroutine packages_per_pmfile in
https://github.com/andk/pause/blob/master/lib/PAUSE/pmfile.pm
There are two problems here:
How do I change the behaviour of a script when executed as a standalone and when used as a module?
How do I discover the package name of a piece of code I just compiled?
The general answer to question 2 is: You don't, as any compilation unit may contain an arbitrary number of packages.
Anyway, here are three possible solutions:
Name your modules so that you already know the name when you load it.
Have each module register itself at a central rendezvous point.
Like #1, but adds autodiscovery of your plugins.
The simplest solution is to put all of the API in an ordinary module, and put the standalone logic in a seperate script:
/the/location/
Module/
A.pm
B.pm
a-standalone.pl
b-standalone.pl
Where each standalone basically looks like
use Module::A;
Module::A->run();
If another script wants to reuse that code, it does
use lib "/the/location";
use Module::A;
...
If the loading happens on runtime, then Module::Runtime helps here:
use Module::Runtime 'use_module';
use lib "/the/location";
my $mod_a = use_module('Module::A');
$mod_a->run();
It isn't strictly necessary to place the contents of a-standalone.pl and Module/A.pm into separate files, although that is clearer. If you want to conditionally run code in a module only if it is used as a script, you can utilize the unless(caller) trick.
Of course all of this is tricksing: Here we determine the file name from the module name, not the other way round – which as I already mentioned we cannot do.
What we can do is have each module register itself at a certain predefined location, e.g. by
Rendezvous::Point->register(__FILE__ => __PACKAGE__);
Of course the standalone version has to shield against the possibility that there is no Rendezvous::Point, therefore:
if (my $register = Rendezvous::Point->can("register")) {
$register->(__FILE__ => __PACKAGE__);
}
Eh, this is silly and violates DRY. So let's create a Rendezvous::Point module that takes care of this:
In /the/location/Rendezvous/Point.pm:
package Rendezvous::Point;
use strict; use warnings;
my %modules_by_filename;
sub get {
my ($class, $name) = #_;
$modules_by_filename{$name};
}
sub register {
my ($file, $package) = #_;
$modules_by_filename{$file} = $package;
}
sub import {
my ($class) = #_;
$class->register(caller());
}
Now, use Rendezvous::Point; registers the calling package, and the module name can be retrived by the absolute path.
The script that wants to use the various modules now does:
use "/the/location";
use Rendezvous::Point (); # avoid registering ourself
my $prefix = "/the/location";
for my $filename (map "$prefix/$_", qw(Module/A.pm Module/B.pm)) {
require $filename;
my $module = Rendezvous::Point->get($filename)
// die "$filename didn't register itself at the Rendezvous::Point";
$module->run();
}
Then there are fully featured plugin systems like Module::Pluggable. This system works by looking at all paths were Perl modules may reside, and loads them if they have a certain prefix. A solution with that would look like:
/the/location/
MyClass.pm
MyClass/
Plugin/
A.pm
B.pm
a-standalone.pl
b-standalone.pl
Everything is just like with the first solution: Standalone scripts look like
use lib "/the/location/";
use MyClass::Plugin::A;
MyClass::Plugin::A->run;
But MyClass.pm looks like:
package MyClass;
use Module::Pluggable require => 1; # we can now query plugins like MyClass->plugins
sub run {
# Woo, magic! Works with inner packages as well!
for my $plugin (MyClass->plugins) {
$plugin->run();
}
}
Of course, this still requires a specific naming scheme, but it auto-discovers possible plugins.
As mentioned before it is not possible to look up the namespace of a 'required' package without extra I/O, guessing or assuming.
Like Rick said before, one have to intrude the namespace of the caller or better 'main'. I prefer to inject specific hooks within a BEGIN block of the 'required' package.
#VENDOR/App/SocketServer/Protocol/NTP.pm
package VENDOR::App::SocketServer::Protocol::NTP;
BEGIN {
no warnings;
*main::HANDLE_REQUEST = \&HANDLE_REQUEST;
}
sub HANDLE_REQUEST {
}
#VENDOR/App/SocketServer.pm
my $userPackage= $ARGV[0];
require $userPackage;
main::HANDLE_REQUEST();
Instead of *main:: you can get more specific with *main::HOOKS::HANDLE_REQUESTS i.e. This enables you to resolve all injected hooks easily within the caller by iterating over the HOOK's namespace portion.
foreach my $hooks( keys %main::HOOKS ) {
}

Overriding a module that is used by a program I'm testing

I am revising a Perl program and I wanted a test harness that could run the original version of the program (call it launch_rockets.pl) and collect the standard output, but somehow skip the system calls that occur inside launch_rockets.pl. The following code successfully overrides system inside launch_rockets.pl:
use subs qw(system);
my $SYSTEM_SUCCESS = 0;
sub system {
print "***\n";
print "system #_\n";
print "***\n\n";
return $SYSTEM_SUCCESS;
}
local #ARGV = #test_args;
do 'launch_rockets.pl';
So far so good. But launch_rockets.pl also contains
use Proc::Background;
and later
Proc::Background->new('perl', 'launch_missiles.pl');
I could copy launch_rockets.pl into a sandbox where Proc::Background is replaced by a stub, but I was wondering if there was any override strategy that would be effective inside a do FILE call in the file's original environment.
use lib '/my/test/library/path';
lib prepends the directory to #INC, so /my/test/library/path/Proc/Background.pm will be the file that gets loaded. Put whatever code you want in there.
Another alternative would be:
{
package Proc::Background;
... # Put stub code here
} # end of package Proc::Background
$INC{'Proc/Background.pm'} = 1; # Make Perl think Proc::Background is loaded