Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't get Verilog::Netlist::Net object from Pin for partial vector #1201

Closed
veripoolbot opened this issue Sep 10, 2017 · 9 comments
Closed

Comments

@veripoolbot
Copy link
Collaborator


Author Name: Leon Medpum
Original Redmine Issue: 1201 from https://www.veripool.org


using git version: 5f176d4
I have the following Verilog:

module submod1 (
     output    net1,
     output    net2a,
     output [1:0] net3
);
endmodule

module submod2 (
     input [1:0]   net4a,
     input net5,
);
endmodule

module top ();
     wire       net1;
     wire       \net2[0] ;
     wire [1:0] net3;
     wire [3:0] net4;

     submod1 submod1
     (.net1,
      .net2a (net2[0]),
      .net3
     );
     submod2 submod2
      (.net4a (net4[2:1]),
       .net5 (net4[0])
     );
endmodule

If (after linking) I query the pins for submod2, I query the pins for cell submod2, I see net4a and net5. If I query the pinselects() for each pin, I see respectively 'net4[2:1]' and 'net4[0]', but if i query the nets() for net4a or net5, I do not get any results. The PinSelection object does not provide any mechanism to locate the Verilog::Netlist::Net object. What is the recommended method to trace the connectivity? I thought this was the purpose of the msb/lsb attributes of the array returned by Verilog::Netlist::Pin->nets()

As a side note, the nets() fundtion works fine when tracing the connectivity through submod1

@veripoolbot
Copy link
Collaborator Author


Original Redmine Comment
Author Name: Stefan Tauner (@stefanct)
Original Date: 2017-09-11T12:08:41Z


Leon Medpum wrote:

using git version: 5f176d4
I have the following Verilog:

module top ();
[…]
    wire       \net2[0] ;
[…]
     .net2a (net2[0]),


Hi Leon,

I don't think the declaration of the wire is correct thus there is no @net2@. I am not sure if Verilog-Perl should warn about that, but if this is fixed (@wire [0:0] \net2 ;@) the output of my test program (below) shows the correct nets with both methods.

```<code class="perl">
#!/usr/bin/perl

use strict;
use warnings;

use Verilog::Netlist;
my $files = ['/tmp/issue1201.v'];
my $nl_opts = [link_read_nonfatal=>0, keep_comments => 1, use_pinselects => 1];
1. Setup options so files can be found
use Verilog::Getopt;
my $opt = new Verilog::Getopt;
$opt->parameter( "+incdir+verilog",
		 "-y","verilog",
		 );
my $nl = new Verilog::Netlist (options => $opt,
			       link_read_nonfatal=>0,
			       keep_comments => 0,
			       @{$nl_opts});
foreach my $file (@{$files}) {
     $nl->read_file (filename=>$file);
}

$nl->link();

foreach my $mod ($nl->top_modules_sorted) {
     show_hier ($mod, "  ", "", "");
}

sub show_hier {
     my $mod = shift;
     my $indent = shift;
     my $hier = shift;
     my $cellname = shift;
     if (!$cellname) {$hier = $mod->name;} #top modules get the design name
     else {$hier .= ".$cellname";} #append the cellname
     printf ("%-45s %s\n", $indent."Module ".$mod->name,$hier);
     foreach my $sig ($mod->ports_sorted) {
	printf ($indent."     %sput %s\n", $sig->direction, $sig->name);
     }
     foreach my $cell ($mod->cells_sorted) {
	printf ($indent. "    Cell %s\n", $cell->name);
	foreach my $pin ($cell->pins_sorted) {
	    printf ($indent."     .%s:\n", $pin->name);
	    printf ($indent."     via nets:\n");
	    foreach my $sel ($pin->nets) {
		printf ($indent.$indent."     .%s\n", $sel->{net}->name);
	    }
	    printf ($indent."     via pinselects:\n");
	    foreach my $sel ($pin->pinselects) {
		printf ($indent.$indent."     .%s[%s:%s]\n", $sel->netname, defined($sel->msb) ? $sel->msb : "<undef>",  defined($sel->lsb) ? $sel->lsb : "<undef>");
		printf ($indent.$indent."     .%s\n", $sel->bracketed_msb_lsb);
	    }
	}
	show_hier ($cell->submod, $indent."  ", $hier, $cell->name) if $cell->submod;
     }
}
</code>

@wilson: However, the netnames function does not really make sense as is IMHO. I kinda lost track about who proposed which parts of the API but I guess the netnames function is a potpourri of both our ideas and the outcome is probably not what either of us wanted. :) As is the nets function is a bad copy of the pinselects function with the disadvantage of returning untyped hashes similar to Verilog::Netlist::PinSelection.
I think the most useful change would be to simply store the Nets in there without the msb/lsb information. If that's needed the user could use the pinselects function anyway. What do you think?

KR, Stefan

@veripoolbot
Copy link
Collaborator Author


Original Redmine Comment
Author Name: Leon Medpum
Original Date: 2017-09-11T13:49:46Z


The net2[0] is legal verilog. I agree the net is not 'net2' it is actually 'net2[0]' The '' and space at the end make the special characters part of the net. Our verilog has a lot of crazy syntax, and I'm testing out different corner cases.

I don't think I communictaed my problem well. Here is the test program I used:

#!/usr/bin/env perl                                           

use strict;
use warnings;

use Verilog::Netlist;                                               
use Data::Dumper;                                                   

1. prepare netlist
my $Opt = new Verilog::Getopt(filename_expansion=>1);
$Opt->libext(".sv");                                 

my $nl = new Verilog::Netlist(
                  options => $Opt,
                  synthesis => 0, 
                  # link_read_nonfatal => 1
                  );                       
$nl->read_file(filename => './top.sv');   

1. read in any sub modules
$nl->link();             
$nl->lint();             
$nl->exit_if_error();    

print "Module names in netlist:\n";
for my $mod ( $nl->modules() ) {   
    print $mod->name(), "\n";       
}                                  
print "\n";                        

for my $mod ( $nl->top_modules_sorted() ) {
    show_hier($mod, '', '', '');            
}                                          

sub show_hier {
    # Recursively descend through module hierarchy,
    # printing each module name and full hierarchical
    # specifier, all module port names, and all
    # instance port connections.
    my $mod      = shift;
    my $indent   = shift;
    my $hier     = shift;
    my $cellname = shift;
    if ($cellname) {
        $hier .= ".$cellname";
    }
    else {
        $hier = $mod->name();
    }
    print "${indent}ModuleName=", $mod->name(), "  HierInstName=$hier\n";
    $indent .= '   ';

    for my $sig ($mod->ports_sorted()) {
        print $indent, 'PortDir=', sigdir($sig->direction()), ' PortName=', $sig->name(), "\n";
    }

    for my $cell ($mod->cells_sorted()) {
        for my $pin ($cell->pins_sorted()) {
           my @nets = map {netname($_)} $pin->nets();
           if (! @nets) {
               #@nets = $pin->pinselects();
               #print Dumper(@nets);
           }
           #my @nets = map {$_->name()} $pin->nets();
           print $indent, 'CellName=', $cell->name(), ' PinName=', $pin->name(), ' NetName=(', join(", ", @nets), ")", "\n";
        }

        show_hier($cell->submod(), $indent, $hier, $cell->name()) if $cell->submod();
    }
}

sub sigdir {
    # Change "in"  to "input"
    # Change "out" to "output"
    my $dir = shift;
    return ($dir eq 'inout') ? $dir : $dir . 'put';
}

sub netname {
     my($net) = @_;
     if (! $net->{msb}) {
         return $net->{net}->name();
     } else {
         #print Dumper($net);
         return $net->{net}->name() . "[$net->{msb}:$net->{lsb}]";
     }
}

The result looks like:

Module names in netlist:
submod2
top
submod1

ModuleName=top  HierInstName=top
    CellName=submod1 PinName=net1 NetName=(net1)
    CellName=submod1 PinName=net2a NetName=(\net2[0] )
    CellName=submod1 PinName=net3 NetName=(net3[1:0])
    ModuleName=submod1  HierInstName=top.submod1
       PortDir=output PortName=net1
       PortDir=output PortName=net2a
       PortDir=output PortName=net3
    CellName=submod2 PinName=net4a NetName=()
    CellName=submod2 PinName=net5 NetName=()
    ModuleName=submod2  HierInstName=top.submod2
       PortDir=input PortName=net4a
       PortDir=input PortName=net5

For CellName=submod1 this is exactly what i expect. For CellName=submod2, the 'NetName' is empty which is not what I expect.

@veripoolbot
Copy link
Collaborator Author


Original Redmine Comment
Author Name: Leon Medpum
Original Date: 2017-09-11T14:00:12Z


After looking at it further, I don't understand why your code seems to misdetect the net[0] and correctly handles the net4[], whereas mine is the reverse...

@veripoolbot
Copy link
Collaborator Author


Original Redmine Comment
Author Name: Leon Medpum
Original Date: 2017-09-11T15:13:20Z


On further follow up, this is due to the 'use_pinselects => 1' option. I do noty understand why the behavior changes when using this option.

@veripoolbot
Copy link
Collaborator Author


Original Redmine Comment
Author Name: Stefan Tauner (@stefanct)
Original Date: 2017-09-11T15:14:26Z


Leon Medpum wrote:

The net2[0] is legal verilog. I agree the net is not 'net2' it is actually 'net2[0]' The '' and space at the end make the special characters part of the net. Our verilog has a lot of crazy syntax, and I'm testing out different corner cases.

No, @net2[0]@ is not valid (but that's not what you wrote initially anyway ;)
The backslash has to be at the start of the identifier (cf. IEEE 1364-2005 Syntax Figure 12-6).
If you really want to use an escaped identifier as in your wire specification then you need to use the complete identifier later on as well.
The following works as expected:

module submod1 (
     output    net1,
     output    net2a,
     output [1:0] net3
);
endmodule

module submod2 (
     input [1:0]   net4a,
     input net5,
);
endmodule

module top ();
     wire       net1;
     wire       \net2[0] ;
     wire [1:0] net3;
     wire [3:0] net4;

     submod1 submod1
     (.net1,
      .net2a (\net2[0] ),
      .net3
     );
     submod2 submod2
      (.net4a (net4[2:1]),
       .net5 (net4[0])
     );
endmodule


@veripoolbot
Copy link
Collaborator Author


Original Redmine Comment
Author Name: Stefan Tauner (@stefanct)
Original Date: 2017-09-11T15:17:56Z


Leon Medpum wrote:

On further follow up, this is due to the 'use_pinselects => 1' option. I do noty understand why the behavior changes when using this option.

Because this option was added to parse the LSB/MSB syntax. Previously this was not covered at all in Verilog-Perl and the identifiers were not really distinguished from the indices at all.

@veripoolbot
Copy link
Collaborator Author


Original Redmine Comment
Author Name: Leon Medpum
Original Date: 2017-09-11T16:36:09Z


Sorry, I don't know how to display the bus notation in this form without the pre tags. The backslash was just so it wouldn't superscript. Thank you for identifying the typo in my verilog, agreed that is not supposed to work.

Since the pinselect objects are created with and without the use_pinselect option, I hadn't realized it changed the behavior in this way. Thank you for your help. Feel free to close this issue.

@veripoolbot
Copy link
Collaborator Author


Original Redmine Comment
Author Name: Utkarsh Khanna
Original Date: 2019-06-10T05:58:06Z


hello all ,

can u please tell me what is this Opt->libext(".sv") doing here?
and also how can we use standard verilog libraries for perl scripts?
Please help!

@veripoolbot
Copy link
Collaborator Author


Original Redmine Comment
Author Name: Wilson Snyder (@wsnyder)
Original Date: 2019-06-10T11:30:25Z


Your libext post seems unrelated to this issue, in the future please make a new issue or forum post. But anyways the libext setting is the same as +libext+.sv passed to your simulator, used to resolve module names to filenames. Or, just pass every filename needed through the command line (e.g. to read_file).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant