Skip to content

Commit 09b456d

Browse files
committed
avoid double-counting assignments if AUTOINTERFACE, AUTONET, AUTONC are combined
1 parent be323e7 commit 09b456d

File tree

2 files changed

+91
-67
lines changed

2 files changed

+91
-67
lines changed

verilogpp

Lines changed: 88 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1287,7 +1287,8 @@ sub init {
12871287
$self->{width} = shift;
12881288
$self->{unpacked} = undef;
12891289
# Count the ports this net is connected to:
1290-
$self->{count} = { 'input' => 0, 'output' => 0, 'inout' => 0, 'modport' => 0 };
1290+
$self->{count} = { 'input' => 0, 'output' => 0, 'inout' => 0, 'modport' => 0,
1291+
'assign_to' => 0, 'assign_from' => 0 };
12911292
}
12921293

12931294
sub set_unpacked($$) {
@@ -1314,6 +1315,12 @@ sub MakeCompatibleWith($$) {
13141315
if ($#{$other_net->{unpacked}} > $#{$self->{unpacked}}) { $self->{unpacked} = $other_net->{unpacked}; }
13151316
}
13161317

1318+
sub ClearAssignmentCounts($) {
1319+
my $self = shift;
1320+
$self->{count}->{"assign_to"} = 0;
1321+
$self->{count}->{"assign_from"} = 0;
1322+
}
1323+
13171324
sub CountConnection {
13181325
my $self = shift;
13191326
my $dir = shift;
@@ -1322,12 +1329,27 @@ sub CountConnection {
13221329
$self->{count}->{$dir} += 1;
13231330
}
13241331

1325-
sub NumberOfConnections {
1332+
sub NumberOfOutputConnections {
13261333
my $self = shift;
1327-
my $dir = shift;
1328-
return $self->{count}->{$dir};
1334+
return $self->{count}->{'output'} + $self->{count}->{'assign_to'};
1335+
}
1336+
1337+
sub NumberOfInputConnections {
1338+
my $self = shift;
1339+
return $self->{count}->{'input'} + $self->{count}->{'assign_from'};
1340+
}
1341+
1342+
sub NumberOfInoutConnections {
1343+
my $self = shift;
1344+
return $self->{count}->{'inout'};
1345+
}
1346+
1347+
sub NumberOfModportConnections {
1348+
my $self = shift;
1349+
return $self->{count}->{'modport'};
13291350
}
13301351

1352+
13311353
sub Declaration() {
13321354
my $self = shift;
13331355
my $no_regs = shift || 0;
@@ -1339,7 +1361,7 @@ sub Declaration() {
13391361
if (!($no_regs || $config{"autonet_allwires"})) {
13401362
if ($self->{count}->{inout} > 0) {
13411363
$type = "tri";
1342-
} elsif ($self->{count}->{output} == 0) {
1364+
} elsif ($self->NumberOfOutputConnections() == 0) {
13431365
$type = "reg";
13441366
}
13451367
}
@@ -1382,13 +1404,13 @@ sub Declaration() {
13821404
sub Port {
13831405
my $self = shift;
13841406
my @return = ('output');
1385-
if ($self->NumberOfConnections('inout') > 0) {
1407+
if ($self->NumberOfInoutConnections() > 0) {
13861408
@return = ('inout');
1387-
} elsif ($self->NumberOfConnections('output') == 0) {
1409+
} elsif ($self->NumberOfOutputConnections() == 0) {
13881410
@return = ('input');
13891411
}
13901412
push @return, @{$self->Declaration(1)};
1391-
if ($self->NumberOfConnections('modport') == 1) {
1413+
if ($self->NumberOfModportConnections() == 1) {
13921414
# this is an interface. Replace the first two elements.
13931415
shift @return for 1..2;
13941416
unshift(@return, $self->{intf_modport});
@@ -1422,6 +1444,29 @@ sub init {
14221444
}
14231445
}
14241446

1447+
sub reset_assignment_counts($) {
1448+
my $self = shift;
1449+
for my $netname (keys %{$self->{NETS}}) {
1450+
$self->{NETS}->{$netname}->ClearAssignmentCounts();
1451+
}
1452+
}
1453+
1454+
sub recount_assignments($$) {
1455+
my $self = shift;
1456+
my $my_interface = shift;
1457+
1458+
# mark assignments
1459+
$self->reset_assignment_counts();
1460+
for my $symbol_to (keys %{$my_interface->{assigns}}) {
1461+
# like an output from an assignment block:
1462+
$self->keep_track_of_assignment($symbol_to, "assign_to");
1463+
}
1464+
for my $symbol_from (keys %{$my_interface->{assign_from}}) {
1465+
# like an input to an assignment block:
1466+
$self->keep_track_of_assignment($symbol_from, "assign_from");
1467+
}
1468+
}
1469+
14251470
sub GetPackageIncludes {
14261471
my $self = shift;
14271472

@@ -2363,20 +2408,15 @@ sub expand_autonc($$) {
23632408
foreach my $line (split(/\s*\n\s*/, $macro)) {
23642409
chomp($line);
23652410
if ($line =~ m/^\s*$/) {continue;}
2366-
if ($line =~ m/^\/(.*)\/$/) {push @regexes, $1;}
2411+
if ($line =~ m/^!?m?\/(.*)\/;?$/) {push @regexes, $line;}
23672412
else {push @names, $line;}
23682413
}
23692414

23702415
# parse the input and output ports of this module
23712416
my $my_interface = new ModuleSpec()->parse_prototype($self->{text});
23722417

23732418
# mark assignments
2374-
for my $symbol_to (keys %{$my_interface->{assigns}}) {
2375-
$self->keep_track_of_assignment($symbol_to, "output");
2376-
}
2377-
for my $symbol_from (keys %{$my_interface->{assign_from}}) {
2378-
$self->keep_track_of_assignment($symbol_from, "input");
2379-
}
2419+
$self->recount_assignments($my_interface);
23802420

23812421
my @sigs = sort keys %{$self->{NETS}};
23822422
foreach my $s (@sigs) {
@@ -2391,10 +2431,9 @@ sub expand_autonc($$) {
23912431
$found = 1;
23922432
} else {
23932433
foreach my $re (@regexes) {
2394-
if ($s =~ $re) {
2395-
$found = 1;
2396-
last;
2397-
}
2434+
$_ = $s;
2435+
my $result = eval($re);
2436+
if ($result) { $found = 1; last; }
23982437
}
23992438
}
24002439

@@ -2406,15 +2445,15 @@ sub expand_autonc($$) {
24062445
next if ($s eq $main::config{"clock"});
24072446
next if ($s eq $main::config{"reset_n"});
24082447

2409-
if ($ref->NumberOfConnections('inout') > 0) {
2448+
if ($ref->NumberOfInoutConnections() > 0) {
24102449
# ignore inout signals
2411-
} elsif ($ref->NumberOfConnections('modport') > 0) {
2450+
} elsif ($ref->NumberOfModportConnections() > 0) {
24122451
# ignore interfaces
2413-
} elsif ($ref->NumberOfConnections('output') == 0) {
2452+
} elsif ($ref->NumberOfOutputConnections() == 0) {
24142453
# no drivers, so assign to zero.
24152454
push @tieoffs, $s;
24162455
$ref->{count}->{output} = 1;
2417-
} elsif ($ref->NumberOfConnections('input') == 0) {
2456+
} elsif ($ref->NumberOfInputConnections() == 0) {
24182457
# no loads, so add to lint_unused signal list.
24192458
push @unused, $s;
24202459
$ref->{count}->{input} = 1;
@@ -2539,6 +2578,7 @@ sub expand_autointerface($$) {
25392578

25402579
# parse the input and output ports of this module
25412580
my $my_interface = new ModuleSpec()->parse_prototype($self->{text});
2581+
$self->recount_assignments($my_interface);
25422582

25432583
my @sigs = sort keys %{$self->{NETS}};
25442584
my @ports = ();
@@ -2558,7 +2598,7 @@ sub expand_autointerface($$) {
25582598
$_ = $s;
25592599
foreach my $filt (@filters) {
25602600
my $result = eval($filt);
2561-
if ($result) { $matched = 1; }
2601+
if ($result) { $matched = 1; last; }
25622602
}
25632603
if (!$matched) {
25642604
next;
@@ -2572,18 +2612,18 @@ sub expand_autointerface($$) {
25722612
#
25732613
# ... if the signal is connected to at least one bidirectional port,
25742614
# then we surface it as a bidirectional port.
2575-
if ($ref->NumberOfConnections('inout') > 0) {
2615+
if ($ref->NumberOfInoutConnections() > 0) {
25762616
push (@ports, [' ', $ref->Port()]);
25772617
# ... or, if it is not connected to any output ports, then it must
25782618
# be an input of the enclosing interface.
2579-
} elsif ($ref->NumberOfConnections('output') == 0) {
2619+
} elsif ($ref->NumberOfOutputConnections() == 0) {
25802620
if (!exists($my_interface->{assigns}->{$ref->{name}})) {
25812621
push (@ports, [' ', $ref->Port()]);
25822622
}
25832623
# ... or, if it is not connected to any input ports (ie. nobody
25842624
# within the module is listening to this signal), then it must
25852625
# be intended to be an output port of the enclosing interface.
2586-
} elsif ($ref->NumberOfConnections('input') == 0) {
2626+
} elsif ($ref->NumberOfInputConnections() == 0) {
25872627
push (@ports, [' ', $ref->Port()]);
25882628
}
25892629
}
@@ -2615,24 +2655,6 @@ sub expand_autointerface($$) {
26152655
}
26162656
}
26172657

2618-
sub CountAssignments {
2619-
my $self = shift;
2620-
my $my_interface = shift;
2621-
2622-
foreach my $s (keys %{$my_interface->{assigns}}) {
2623-
if (defined($self->{NETS}->{$s})) {
2624-
my $ref = $self->{NETS}->{$s};
2625-
$ref->CountConnection('output');
2626-
}
2627-
}
2628-
foreach my $s (keys %{$my_interface->{assign_from}}) {
2629-
if (defined($self->{NETS}->{$s})) {
2630-
my $ref = $self->{NETS}->{$s};
2631-
$ref->CountConnection('input');
2632-
}
2633-
}
2634-
}
2635-
26362658

26372659
$MacroHelp{'AUTONET'} = <<EOT ;
26382660
Usage:
@@ -2752,7 +2774,7 @@ sub expand_autonet($$) {
27522774

27532775
# parse the input and output ports of this module
27542776
my $my_interface = new ModuleSpec()->parse_prototype($self->{text});
2755-
$self->CountAssignments($my_interface);
2777+
$self->recount_assignments($my_interface);
27562778

27572779
my @sigs = sort keys %{$self->{NETS}};
27582780

@@ -2793,52 +2815,53 @@ sub expand_autonet($$) {
27932815
# add it to autonets list of nets:
27942816
my $ref = $self->{NETS}->{$s};
27952817

2796-
if ($skipif && $ref->NumberOfConnections('modport') > 0) {
2818+
if ($skipif && $ref->NumberOfModportConnections() > 0) {
27972819
next;
27982820
}
27992821

28002822
my $warning = "";
28012823
if ($warn) {
2802-
if (($ref->NumberOfConnections('input') == 0) &&
2803-
($ref->NumberOfConnections('inout') == 0)) {
2824+
if (($ref->NumberOfInputConnections() == 0) &&
2825+
($ref->NumberOfInoutConnections() == 0)) {
28042826
$warning = " // WARNING: zero load";
28052827
}
2806-
if (($ref->NumberOfConnections('output') == 0) &&
2807-
($ref->NumberOfConnections('inout') == 0)) {
2828+
if (($ref->NumberOfOutputConnections() == 0) &&
2829+
($ref->NumberOfInoutConnections() == 0)) {
28082830
$warning = " // WARNING: zero drivers";
28092831
}
2810-
if ($ref->NumberOfConnections('output') > 1) {
2811-
$warning = " // WARNING: multiple drivers";
2832+
if ($ref->NumberOfOutputConnections() > 1) {
2833+
my $x = $ref->NumberOfOutputConnections();
2834+
$warning = " // WARNING: multiple drivers ($x drivers)";
28122835
}
28132836
}
28142837

28152838
if ($s =~ m/^(.*_)clk$/) {
28162839
push(@cb_clocks, $1);
28172840
}
2818-
elsif (($ref->NumberOfConnections('input') == 0) &&
2819-
($ref->NumberOfConnections('output') != 0) &&
2820-
($ref->NumberOfConnections('inout') == 0)) {
2841+
elsif (($ref->NumberOfInputConnections() == 0) &&
2842+
($ref->NumberOfOutputConnections() != 0) &&
2843+
($ref->NumberOfInoutConnections() == 0)) {
28212844
$cb_signals->AddSignal($s, "input");
28222845
}
2823-
elsif (($ref->NumberOfConnections('input') != 0) &&
2824-
($ref->NumberOfConnections('output') == 0) &&
2825-
($ref->NumberOfConnections('inout') == 0)) {
2846+
elsif (($ref->NumberOfInputConnections() != 0) &&
2847+
($ref->NumberOfOutputConnections() == 0) &&
2848+
($ref->NumberOfInoutConnections() == 0)) {
28262849
$cb_signals->AddSignal($s, "output");
28272850
}
2828-
elsif (($ref->NumberOfConnections('input') == 0) &&
2829-
($ref->NumberOfConnections('output') == 0) &&
2830-
($ref->NumberOfConnections('inout') != 0)) {
2851+
elsif (($ref->NumberOfInputConnections() == 0) &&
2852+
($ref->NumberOfOutputConnections() == 0) &&
2853+
($ref->NumberOfInoutConnections() != 0)) {
28312854
$cb_signals->AddSignal($s, "inout");
28322855
}
28332856

28342857
# determine what to initialize the register too, if needed.
28352858
my $assignment = ""; # empty string by default
28362859
if ($init) {
2837-
if ($ref->NumberOfConnections('modport') > 0) {
2860+
if ($ref->NumberOfModportConnections() > 0) {
28382861
$assignment = "";
2839-
} elsif ($ref->NumberOfConnections('inout') > 0) {
2862+
} elsif ($ref->NumberOfInoutConnections() > 0) {
28402863
$assignment = " = 'Z";
2841-
} elsif ($ref->NumberOfConnections('output') == 0) {
2864+
} elsif ($ref->NumberOfOutputConnections() == 0) {
28422865
$assignment = " = '0";
28432866
}
28442867
if ($assignment && defined($ref->{unpacked})) {

verilogpp_tests/warnings.vpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,19 @@ reg [`HARD2PARSE_COMMAND_WORD] control_input; // WARNING: zero drivers
2424
wire [`HARD2PARSE_STATUS_WORD] control_output; // WARNING: zero load
2525
wire [15:0] data_to_foobar; // WARNING: zero load
2626
wire data_to_foobar_valid; // WARNING: zero load
27-
reg [31:0] foo_in32; // WARNING: zero drivers
27+
wire [31:0] foo_in32;
2828
word_t foo_in_word; // WARNING: zero drivers
2929
reg foobar_clear_to_send; // WARNING: zero drivers
3030
wire foobar_ready_to_send; // WARNING: zero load
3131
wire [31:0] in32;
3232
word_t in_word; // WARNING: zero drivers
33-
wire [31:0] out32; // WARNING: multiple drivers
33+
wire [31:0] out32; // WARNING: multiple drivers (3 drivers)
3434
reg [`HARD2PARSE_COMMAND__SLOT_WIDTH-1:0] slot; // WARNING: zero drivers
3535
/*PPSTOP*/
3636

3737
// this should disable the warning for axi_rid
3838
assign axi_rid = 5;
39+
assign foo_in32 = 32'd20;
3940

4041
/**INST bar.v u_bar1**/
4142
/*PPSTART*/

0 commit comments

Comments
 (0)