veripool / verilog-perl

Verilog parser, preprocessor, and related tools for the Verilog-Perl package
https://www.veripool.org/verilog-perl
Artistic License 2.0
121 stars 34 forks source link

Verilog::Netlist::PinSelection->msb doesn't return anything. #1500

Closed veripoolbot closed 5 years ago

veripoolbot commented 5 years ago

Author Name: Shareef Jalloq Original Redmine Issue: 1500 from https://www.veripool.org


I'm trying to process a netlist to pull out port and net names for cells and am having some trouble. If I try to get a PinSelection object, I can query the name but the lsb/msb accessors don't return anything.

So in the following example...

foreach my $pin (@{$pins}) {
        my $portname = $pin->portname;
        my @pins     = $pin->pinselects;
        my $netname  = join(' ', map { $_->netname } @pins);
        my $msb      = join(' ', map { $_->msb } @pins);
        print "Pin msb is $msb\n";
        print "Pin name $portname is connected to net $netname\n";

    }

I'm getting the output...

Pin msb is 
Pin name I is connected to net IMSK
Pin msb is 
Pin name ZN is connected to net IMSKB

where both nets are defined as...

     wire [7:0] INTR;
     wire [7:0] IMSKB;

There also seems to be a useful accessor in Verilog::Netlist::Pin->nets but I can't work out how to use this. If I print the bare object I'm told it's a hash rather than an array which the docs say it is.

Admittedly this is the first time I've used Perl in 10 years so I'm a little rusty.

Cheers.

veripoolbot commented 5 years ago

Original Redmine Comment Author Name: Wilson Snyder (@wsnyder) Original Date: 2019-09-04T01:41:59Z


Pin msb/lsbs are for when you have e.g. ".pin(connects_to[3:0])". To get the range of a declaration (e.g. "wire [7:0]") you need to go to the net object then look at the type, e.g.

for my $net ($pin->nets) {
    print $net->msb,":",$net->lsb;
veripoolbot commented 5 years ago

Original Redmine Comment Author Name: Shareef Jalloq Original Date: 2019-09-04T09:20:35Z


OK, thanks. I tried using Verilog::Netlist::Pin->nets but I just get an unblessed reference error. What am I doing wrong?

I store an array reference in a hash and then iterate over the pins. I can call Pin->portname, Pin->pinselects, but calling Pin->nets fails.

foreach my $key (keys %cells) {
    my $inst = $cells{$key}{_instance};
    my $mod  = $cells{$key}{_module};
    my $rng  = $cells{$key}{_range};
    my $pins = $cells{$key}{_pins}; # array ref

    print "Pins:\n";
    foreach my $pin (@{$pins}) {
        my $portname = $pin->portname;
        print "Portname=", $portname, "\n";
        for my $net ($pin->nets) {
        print "MSB=", $net->msb, "\n";
        }    
    }
     }

produces

Pins:
Portname=VDD
Portname=VSS
Portname=I
Can't call method "msb" on unblessed reference at ./vperl.pl line 47 (#1)
     (F) A method call must know in what package it's supposed to run.  It
     ordinarily finds this out from the object reference you supply, but you
     didn't supply an object reference in this case.  A reference isn't an
     object reference until it has been blessed.  See perlobj.

for the following cell instance:

    input [7:0] IMSK;

     ANTENNABWP30P140 I7[7:0] (
             .I(IMSK),
             .VDD({VDD,VDD,VDD,VDD,VDD,VDD,VDD,VDD}),
             .VSS({VSS,VSS,VSS,VSS,VSS,VSS,VSS,VSS}));

So it seems to not cope with the 8-bit concatenation and then fails completely for the input IMSK.

veripoolbot commented 5 years ago

Original Redmine Comment Author Name: Wilson Snyder (@wsnyder) Original Date: 2019-09-04T10:34:18Z


Try an "if $pin->nets", as there might be nothing to iterate on.

veripoolbot commented 5 years ago

Original Redmine Comment Author Name: Shareef Jalloq Original Date: 2019-09-04T11:32:19Z


Here's a test case for you.

#!/usr/bin/env perl

use strict;
use diagnostics;
use Verilog::Netlist;

1. Prepare netlist
my $nl = new Verilog::Netlist();
foreach my $file ('test.v') {
     $nl->read_file(filename=>$file);
}

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

foreach my $mod ($nl->top_modules_sorted) {
     foreach my $cell ($mod->cells_sorted) {
    if ($cell->range) {
        foreach my $pin ($cell->pins) {
        if ($pin->nets) {
            foreach my $net ($pin->nets) {
            print $net->name;
            }
        }
        }
    }
     }
}
module sub  (A,B,C);

    input wire A;
    input wire B;
    output wire C;

    assign C = A | B;

endmodule // sub

module test (A,B,C);

    input wire [3:0] A;
    input wire [3:0] B;
    output wire [3:0] C;

    sub inst[3:0] (.A (A), .B(B), .C(C));

endmodule // test
veripoolbot commented 5 years ago

Original Redmine Comment Author Name: Wilson Snyder (@wsnyder) Original Date: 2019-09-04T21:39:09Z


Sorry, when the PinSelect stuff got introduced the net function changed in a way it shouldn't have, and so the documentation was also wrong.

Here's what's implemented now:

=item $self->nets Array of hashes the pin connects to. Each hash contains a msb, lsb, and net (a Verilog::Netlist::Net). Only valid after a link.

So do this

         foreach my $pin ($cell->pins) {
             foreach my $nethash ($pin->nets_sorted) {
                 print $nethash->{net}->name;
veripoolbot commented 5 years ago

Original Redmine Comment Author Name: Shareef Jalloq Original Date: 2019-09-05T07:49:07Z


Thanks a lot. Working now.

Edit: Actually, in my case when I have concatenated nets such as

 .pin ({sig,sig}),

what am I supposed to use to get that net? Verilog::Netlist::Pin->nets doesn't return anything for these. Verilog::Netlist::Pin->pinselects returns a PinSelection but from the documentation it doesn't seem like this is the right useage.