Grab the inout port fixer from bsc tree, wire it in

Yosys doesn't understand Verilog-2001 port aliases. Unfortunately
bsc uses those to represent inout ports because it's the only way
to represent a particular kind of shared bus in Verilog source code.

Thankfully, a kind soul at Bluespec Inc made a perl script that
transforms the port alias construct into regular verilog-1995, which
works fine in cases like mine where the only user of the inout port
is a TriState module which tears it apart into separate
input/output/enable signals for the rest of bsc to work with.
This commit is contained in:
David Anderson 2024-09-06 21:08:51 -07:00
parent 0005ad6fe5
commit 6fd040565c
2 changed files with 97 additions and 1 deletions

96
scripts/basicinout.pl Executable file
View File

@ -0,0 +1,96 @@
#!/usr/bin/env perl
# -*-Perl-*-
################################################################################
################################################################################
### NOTE ###
#
# This script comes from the Bluespec source repository,
# https://github.com/B-Lang-org/bsc/blob/main/util/scripts/basicinout.pl
#
# Unlike the rest of this repo, it is licensed under BSD-3-Clause like
# the original, with credit and gratitude to Bluespec Inc. and the
# anonymous programmers who wrote it prior to the open-sourcing of
# Bluespec.
#
### NOTE ###
my %RENAME_PORTS = ();
my %SIGNALS = ();
my %PINS = ();
foreach my $outfile (@ARGV) {
# read the file
next unless open(FILE, $outfile);
my @lines = <FILE>;
close(FILE);
# Locate inout signals
my $inmodule = 0;
my $showedassigns = 0;
my @newlines;
foreach my $line (@lines) {
if ($line =~ m/rename\:\s+(\S+)\=(\S+)/) {
$RENAME_PORTS{$1} = $2;
} elsif ($line =~ m/^\s*module\s*[a-zA-Z0-9_\$]+\s*\(\s*\.(\S+)\(([a-zA-Z0-9_\$]+)\)/) {
$inmodule = 1;
$SIGNALS{$2} = $1;
$PINS{$1} = $2;
$line =~ s/\.(\S+)\(([a-zA-Z0-9_\$]+)\)/$1/;
push @newlines, $line;
} elsif ($line =~ m/^\s*module\s+(\S+)\s*\(/) {
$inmodule = 1;
push @newlines, $line;
} elsif ($line =~ m/^\s*\.(\S+)\(([a-zA-Z0-9_\$]+)\)/ && $inmodule) {
$SIGNALS{$2} = $1;
$PINS{$1} = $2;
$line =~ s/\.(\S+)\(([a-zA-Z0-9_\$]+)\)/$1/;
push @newlines, $line;
} elsif ($line =~ m/\s*inout(.*?)\s*(\S+)\;/) {
my $signal = $2;
my $origsig = $2;
if (exists $SIGNALS{$signal}) {
my $pin = $SIGNALS{$signal};
$signal =~ s/\$/\\\$/g;
$line =~ s/$signal/$pin/;
} else {
print("Failed to locate signal=$signal in module port list (basicinout)!\nPlease report this error to the BSC developers, by opening a ticket\nin the issue database\: https\:\/\/github.com\/B-Lang-org\/bsc\/issues\n\n");
die;
}
push @newlines, $line;
} elsif ($line =~ m/input/ && $inmodule) {
$inmodule = 0;
push @newlines, $line;
} elsif ($line =~ m/\.(\S+)\(([a-zA-Z0-9\$_]+)\)/) {
my $signal = $2;
if (exists $SIGNALS{$signal}) {
my $pin = $SIGNALS{$signal};
$signal =~ s/\$/\\\$/g;
$line =~ s/$signal/$pin/;
}
push @newlines, $line;
} else {
push @newlines, $line;
}
}
# Rename any signals that need renaming
my @renamed_lines;
foreach my $line (@newlines) {
foreach my $signal (keys %RENAME_PORTS) {
my $replacement = $RENAME_PORTS{$signal};
if ($line =~ m/$signal/) {
$line =~ s/([A-Za-z0-9_\$]*$signal)/$replacement/g;
}
}
push @renamed_lines, $line;
}
# write out the new version
open(OFILE, ">${outfile}") or die("Could not create output file: $!\n");
print OFILE @renamed_lines;
close(OFILE);
}
1;

View File

@ -89,7 +89,7 @@ def build(c, target="."):
for target in expand_build_target(target): for target in expand_build_target(target):
out_info, out_verilog, out_bsc = ensure_build_dirs(target, "info", "verilog", "bsc") out_info, out_verilog, out_bsc = ensure_build_dirs(target, "info", "verilog", "bsc")
print(f"Building {target}") print(f"Building {target}")
c.run(f"bsc -aggressive-conditions -check-assert -remove-dollar -remove-empty-rules -remove-false-rules -remove-starved-rules -remove-unused-modules -show-method-conf -show-method-bvi -u -verilog -info-dir {out_info} -vdir {out_verilog} -bdir {out_bsc} -p {target.parent}:vram:lib:%/Libraries -show-module-use -show-compiles {target}") c.run(f"bsc -aggressive-conditions -check-assert -remove-dollar -remove-empty-rules -remove-false-rules -remove-starved-rules -verilog-filter scripts/basicinout.pl -show-method-conf -show-method-bvi -u -verilog -info-dir {out_info} -vdir {out_verilog} -bdir {out_bsc} -p {target.parent}:vram:lib:%/Libraries -show-module-use -show-compiles {target}")
module_name = Path(f"mk{target.stem}") module_name = Path(f"mk{target.stem}")
verilog_main_file = out_verilog / module_name.with_suffix(".v") verilog_main_file = out_verilog / module_name.with_suffix(".v")