From 6fd040565c639e48c0f93cff29c073767b568a0e Mon Sep 17 00:00:00 2001 From: David Anderson Date: Fri, 6 Sep 2024 21:08:51 -0700 Subject: [PATCH] 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. --- scripts/basicinout.pl | 96 +++++++++++++++++++++++++++++++++++++++++++ tasks.py | 2 +- 2 files changed, 97 insertions(+), 1 deletion(-) create mode 100755 scripts/basicinout.pl diff --git a/scripts/basicinout.pl b/scripts/basicinout.pl new file mode 100755 index 0000000..df571d4 --- /dev/null +++ b/scripts/basicinout.pl @@ -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 = ; + 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; diff --git a/tasks.py b/tasks.py index 1df92b4..e40f3c9 100644 --- a/tasks.py +++ b/tasks.py @@ -89,7 +89,7 @@ def build(c, target="."): for target in expand_build_target(target): out_info, out_verilog, out_bsc = ensure_build_dirs(target, "info", "verilog", "bsc") 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}") verilog_main_file = out_verilog / module_name.with_suffix(".v")