diff --git a/bin/eqmap b/bin/eqmap deleted file mode 100755 index 8b4ce2e3..00000000 --- a/bin/eqmap +++ /dev/null @@ -1,93 +0,0 @@ -#!/bin/bash - -# Copyright 2025 The EqMap Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -eo pipefail -LIB="$(dirname $0)/../verilog/lutlang.v" -LIB="$(realpath $LIB)" -SIMLIB="$(dirname $0)/../verilog/simlib.v" -SIMLIB="$(realpath $SIMLIB)" -MKFILE=$1.mk -TOOL=eqmap_fpga - -# Decide whether to use Vivado or Yosys based on the stem given to Make -if [ -z $FSTEM ]; then - FSTEM=yxil -fi - -if [ "$1" == "--help" ] || [ "$2" == "--help" ] || [ "$3" == "--help" ]; then - $TOOL --help -elif [ ! -f "$1" ]; then - echo "First argument must be the input file." - echo "Usage: $0 [$TOOL options]" - echo "Check that file exists and it is the first argument" -else - which yosys > /dev/null || { echo "yosys not found in PATH"; exit 1; } - which $TOOL > /dev/null || { echo "$TOOL not found in PATH"; exit 1; } - - echo "SRCS=\$(wildcard *.v)" > $MKFILE - echo "# Set both Yosys and Vivado to use Ultrascale+ Arch" >> $MKFILE - echo "FAMILY=xcup" >> $MKFILE - echo "PART=xczu3eg-sbva484-1-i" >> $MKFILE - echo "# flatten design before synthesis, no clock buffers, no IO buffers, no carry logic, no MUXes" >> $MKFILE - echo "SYNTH_OPT=-flatten -noclkbuf -noiopad -nocarry -nowidelut -nosrl -ise" >> $MKFILE - echo "YOSYS=yosys # Yosys 0.33 (git sha1 2584903a060)" >> $MKFILE - echo "XILINX_VIVADO?=\$(realpath \$(dirname \$(which vivado))/..)" >> $MKFILE - echo "VIVADO=\$(XILINX_VIVADO)/bin/vivado" >> $MKFILE - echo "" >> $MKFILE - echo ".PHONY: all clean" >> $MKFILE - echo "" >> $MKFILE - echo "all: $1.xil" >> $MKFILE - echo "" >> $MKFILE - echo "clean:" >> $MKFILE - echo " rm -f *.xil *.synth *.ys *.dot *.png" >> $MKFILE - echo "" >> $MKFILE - echo "%.v.synth: %_synth.ys" >> $MKFILE - echo " +\$(YOSYS) -s \$<" >> $MKFILE - echo "" >> $MKFILE - echo "%.v.yxil: %_yxil.ys" >> $MKFILE - echo " +\$(YOSYS) -s \$<" >> $MKFILE - echo "" >> $MKFILE - echo "# This script synthesizes to LUTs" >> $MKFILE - echo "%_yxil.ys: %.v" >> $MKFILE - echo " @echo \"read_verilog \$<\" > \$@" >> $MKFILE - echo " @echo \"synth_xilinx -family \$(FAMILY) \$(SYNTH_OPT)\" >> \$@" >> $MKFILE - echo " @echo \"clean -purge\" >> \$@" >> $MKFILE - echo " @echo \"splitnets -ports -format _\" >> \$@" >> $MKFILE - echo " @echo \"write_verilog -simple-lhs \$<.yxil\" >> \$@" >> $MKFILE - echo "" >> $MKFILE - echo "# This script synthesizes to AND, NOR, XOR, INV, MUXes" >> $MKFILE - echo "%_synth.ys: %.v" >> $MKFILE - echo " @echo \"read_verilog \$<\" > \$@" >> $MKFILE - echo " @echo \"techmap -map $LIB\" >> \$@" >> $MKFILE - echo " @echo \"clean -purge\" >> \$@" >> $MKFILE - echo " @echo \"splitnets -format _\" >> \$@" >> $MKFILE - echo " @echo \"write_verilog -simple-lhs \$<.synth\" >> \$@" >> $MKFILE - echo "" >> $MKFILE - echo "%.v.vxil: %_vxil.tcl" >> $MKFILE - echo " +\$(VIVADO) -mode tcl -source \$< -nolog -nojournal" >> $MKFILE - echo "" >> $MKFILE - echo "%_vxil.tcl: %.v" >> $MKFILE - echo " @echo \"add_files \$<\" > \$@" >> $MKFILE - echo " @echo \"synth_design -top \$* -mode out_of_context -part \$(PART)\" >> \$@" >> $MKFILE - echo " @echo \"write_verilog -force \$<.vxil\" >> \$@" >> $MKFILE - echo " @echo \"quit\" >> \$@" >> $MKFILE - echo "" >> $MKFILE - - - make -f $MKFILE $1.$FSTEM 1>&2 - $TOOL $1.$FSTEM $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13} ${14} ${15} ${16} - rm -f $1.$FSTEM $MKFILE -fi diff --git a/bin/eqmap_vivado b/bin/eqmap_vivado deleted file mode 100755 index 329654d9..00000000 --- a/bin/eqmap_vivado +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -# Copyright 2025 The EqMap Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -eo pipefail - -EQMAP="$(dirname $0)/eqmap" - -FSTEM=vxil $EQMAP $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13} ${14} ${15} ${16} diff --git a/bin/fam b/bin/fam deleted file mode 100755 index 8fc4f5c9..00000000 --- a/bin/fam +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh - -# Copyright 2025 The EqMap Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -eqmap_fpga $@ diff --git a/bin/lvv b/bin/lvv deleted file mode 100755 index 8ccc57d1..00000000 --- a/bin/lvv +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh - -# Copyright 2025 The EqMap Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -eqmap $@ diff --git a/bin/msynth b/bin/msynth deleted file mode 100755 index 056170e8..00000000 --- a/bin/msynth +++ /dev/null @@ -1,94 +0,0 @@ -#!/bin/bash - -# Copyright 2025 The EqMap Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -eo pipefail -LIB="$(dirname $0)/../verilog/celllang.v" -LIB="$(realpath $LIB)" -SIMLIB="$(dirname $0)/../verilog/simlib.v" -SIMLIB="$(realpath $SIMLIB)" -MKFILE=$1.mk -TOOL=eqmap_asic - -# Decide whether to use Vivado or Yosys based on the stem given to Make -if [ -z $FSTEM ]; then - FSTEM=synth -fi - -if [ "$1" == "--help" ] || [ "$2" == "--help" ] || [ "$3" == "--help" ]; then - $TOOL --help -elif [ ! -f "$1" ]; then - echo "First argument must be the input file." - echo "Usage: $0 [$TOOL options]" - echo "Check that file exists and it is the first argument" -else - which yosys > /dev/null || { echo "yosys not found in PATH"; exit 1; } - which $TOOL > /dev/null || { echo "$TOOL not found in PATH"; exit 1; } - - echo "SRCS=\$(wildcard *.v)" > $MKFILE - echo "# Set both Yosys and Vivado to use Ultrascale+ Arch" >> $MKFILE - echo "FAMILY=xcup" >> $MKFILE - echo "PART=xczu3eg-sbva484-1-i" >> $MKFILE - echo "# flatten design before synthesis, no clock buffers, no IO buffers, no carry logic, no MUXes" >> $MKFILE - echo "SYNTH_OPT=-flatten -noclkbuf -noiopad -nocarry -nowidelut -nosrl -ise" >> $MKFILE - echo "YOSYS=yosys # Yosys 0.33 (git sha1 2584903a060)" >> $MKFILE - echo "XILINX_VIVADO?=\$(realpath \$(dirname \$(which vivado))/..)" >> $MKFILE - echo "VIVADO=\$(XILINX_VIVADO)/bin/vivado" >> $MKFILE - echo "" >> $MKFILE - echo ".PHONY: all clean" >> $MKFILE - echo "" >> $MKFILE - echo "all: $1.xil" >> $MKFILE - echo "" >> $MKFILE - echo "clean:" >> $MKFILE - echo " rm -f *.xil *.synth *.ys *.dot *.png" >> $MKFILE - echo "" >> $MKFILE - echo "%.v.synth: %_synth.ys" >> $MKFILE - # Make yosys quiet - echo " +\$(YOSYS) -s \$< >> /dev/null" >> $MKFILE - echo "" >> $MKFILE - echo "%.v.yxil: %_yxil.ys" >> $MKFILE - echo " +\$(YOSYS) -s \$<" >> $MKFILE - echo "" >> $MKFILE - echo "# This script synthesizes to LUTs" >> $MKFILE - echo "%_yxil.ys: %.v" >> $MKFILE - echo " @echo \"read_verilog \$<\" > \$@" >> $MKFILE - echo " @echo \"synth_xilinx -family \$(FAMILY) \$(SYNTH_OPT)\" >> \$@" >> $MKFILE - echo " @echo \"clean -purge\" >> \$@" >> $MKFILE - echo " @echo \"splitnets -ports -format _\" >> \$@" >> $MKFILE - echo " @echo \"write_verilog -simple-lhs \$<.yxil\" >> \$@" >> $MKFILE - echo "" >> $MKFILE - echo "# This script synthesizes to AND, NOR, XOR, INV, MUXes" >> $MKFILE - echo "%_synth.ys: %.v" >> $MKFILE - echo " @echo \"read_verilog \$<\" > \$@" >> $MKFILE - echo " @echo \"techmap -map $LIB\" >> \$@" >> $MKFILE - echo " @echo \"clean -purge\" >> \$@" >> $MKFILE - echo " @echo \"splitnets -ports -format _\" >> \$@" >> $MKFILE - echo " @echo \"write_verilog -simple-lhs \$<.synth\" >> \$@" >> $MKFILE - echo "" >> $MKFILE - echo "%.v.vxil: %_vxil.tcl" >> $MKFILE - echo " +\$(VIVADO) -mode tcl -source \$< -nolog -nojournal" >> $MKFILE - echo "" >> $MKFILE - echo "%_vxil.tcl: %.v" >> $MKFILE - echo " @echo \"add_files \$<\" > \$@" >> $MKFILE - echo " @echo \"synth_design -top \$* -mode out_of_context -part \$(PART)\" >> \$@" >> $MKFILE - echo " @echo \"write_verilog -force \$<.vxil\" >> \$@" >> $MKFILE - echo " @echo \"quit\" >> \$@" >> $MKFILE - echo "" >> $MKFILE - - - make -f $MKFILE $1.$FSTEM 1>&2 - $TOOL $1.$FSTEM $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13} ${14} ${15} ${16} - rm -f $1.$FSTEM $MKFILE -fi diff --git a/bin/opt-verilog b/bin/opt-verilog deleted file mode 100755 index b503dfad..00000000 --- a/bin/opt-verilog +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash - -# Copyright 2025 The EqMap Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -eo pipefail -cargo build --release 2>>/dev/null -if [ "$1" == "--help" ]; then - cargo run --quiet --release -- --help -else - parse-verilog -- $1 | cargo run --quiet --release -- $2 $3 $4 $5 -fi diff --git a/bin/resynth b/bin/resynth deleted file mode 100755 index e1551a51..00000000 --- a/bin/resynth +++ /dev/null @@ -1,99 +0,0 @@ -#!/bin/bash - -# Copyright 2025 The EqMap Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -eo pipefail -LIB="$(dirname $0)/../verilog/lutlang.v" -LIB="$(realpath $LIB)" -SIMLIB="$(dirname $0)/../verilog/simlib.v" -SIMLIB="$(realpath $SIMLIB)" -MKFILE=$1.mk -TOOL=eqmap_fpga - -if [ "$1" == "--help" ] || [ "$2" == "--help" ] || [ "$3" == "--help" ]; then - $TOOL --help -elif [ ! -f "$1" ]; then - echo "First argument must be the input file." - echo "Usage: $0 [$TOOL options]" - echo "Check that file exists and it is the first argument" -else - which yosys > /dev/null || { echo "yosys not found in PATH"; exit 1; } - which $TOOL > /dev/null || { echo "$TOOL not found in PATH"; exit 1; } - ls $LIB > /dev/null || { echo "lib file $LIB not found"; exit 1; } - - echo "SRCS=\$(wildcard *.v)" > $MKFILE - echo "# Set both Yosys and Vivado to use Ultrascale+ Arch" >> $MKFILE - echo "FAMILY=xcup" >> $MKFILE - echo "PART=xczu3eg-sbva484-1-i" >> $MKFILE - echo "# flatten design before synthesis, no clock buffers, no IO buffers, no carry logic, no MUXes" >> $MKFILE - echo "SYNTH_OPT=-flatten -noclkbuf -noiopad -nocarry -nowidelut -ise" >> $MKFILE - echo "YOSYS=yosys # Yosys 0.33 (git sha1 2584903a060)" >> $MKFILE - echo "XILINX_VIVADO?=\$(realpath \$(dirname \$(which vivado))/..)" >> $MKFILE - echo "VIVADO=\$(XILINX_VIVADO)/bin/vivado" >> $MKFILE - echo "" >> $MKFILE - echo ".PHONY: all clean" >> $MKFILE - echo "" >> $MKFILE - echo "all: $1.xil" >> $MKFILE - echo "" >> $MKFILE - echo "clean:" >> $MKFILE - echo " rm -f *.xil *.synth *.ys *.dot *.png" >> $MKFILE - echo "" >> $MKFILE - echo "%.v.synth: %_synth.ys" >> $MKFILE - echo " +\$(YOSYS) -s \$<" >> $MKFILE - echo "" >> $MKFILE - echo "%.v.yxil: %_yxil.ys" >> $MKFILE - echo " +\$(YOSYS) -s \$<" >> $MKFILE - echo "" >> $MKFILE - echo "%.v.inline: %_inline.ys" >> $MKFILE - echo " +\$(YOSYS) -s \$<" >> $MKFILE - echo "" >> $MKFILE - echo "# This script synthesizes to LUTs" >> $MKFILE - echo "%_yxil.ys: %.v" >> $MKFILE - echo " @echo \"read_verilog \$<\" > \$@" >> $MKFILE - echo " @echo \"synth_xilinx -family \$(FAMILY) \$(SYNTH_OPT)\" >> \$@" >> $MKFILE - echo " @echo \"clean -purge\" >> \$@" >> $MKFILE - echo " @echo \"splitnets -format _\" >> \$@" >> $MKFILE - echo " @echo \"write_verilog -simple-lhs \$<.yxil\" >> \$@" >> $MKFILE - echo "" >> $MKFILE - echo "# This script synthesizes to AND, NOR, XOR, INV, MUXes" >> $MKFILE - echo "%_synth.ys: %.v" >> $MKFILE - echo " @echo \"read_verilog \$<\" > \$@" >> $MKFILE - echo " @echo \"techmap -map $LIB\" >> \$@" >> $MKFILE - echo " @echo \"clean -purge\" >> \$@" >> $MKFILE - echo " @echo \"splitnets -format _\" >> \$@" >> $MKFILE - echo " @echo \"write_verilog -simple-lhs \$<.synth\" >> \$@" >> $MKFILE - echo "" >> $MKFILE - echo "%.v.vxil: %_vxil.tcl" >> $MKFILE - echo " +\$(VIVADO) -mode tcl -source \$< -nolog -nojournal" >> $MKFILE - echo "" >> $MKFILE - echo "%_vxil.tcl: %.v" >> $MKFILE - echo " @echo \"add_files \$<\" > \$@" >> $MKFILE - echo " @echo \"synth_design -top \$* -mode out_of_context -part \$(PART)\" >> \$@" >> $MKFILE - echo " @echo \"write_verilog -force \$<.vxil\" >> \$@" >> $MKFILE - echo " @echo \"quit\" >> \$@" >> $MKFILE - echo "" >> $MKFILE - echo "%_inline.ys: %.v" >> $MKFILE - echo " @echo \"read_verilog $SIMLIB\" > \$@" >> $MKFILE - echo " @echo \"read_verilog \$<\" >> \$@" >> $MKFILE - echo " @echo \"flatten\" >> \$@" >> $MKFILE - echo " @echo \"clean -purge\" >> \$@" >> $MKFILE - echo " @echo \"write_verilog -simple-lhs -noattr \$<.inline\" >> \$@" >> $MKFILE - echo "" >> $MKFILE - - - make -f $MKFILE $1.synth 1>&2 - $TOOL $1.synth $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13} ${14} ${15} ${16} - rm -f $1.synth $MKFILE -fi diff --git a/bin/lvv-vivado b/bin/runtool similarity index 71% rename from bin/lvv-vivado rename to bin/runtool index 29909621..e701b071 100755 --- a/bin/lvv-vivado +++ b/bin/runtool @@ -14,4 +14,14 @@ # See the License for the specific language governing permissions and # limitations under the License. -eqmap_vivado $@ +# Wrapper script for unified_eqmap.py + +DIR="$(dirname "$0")" +PYTHON_SCRIPT="$DIR/runtool.py" + +if [ ! -f "$PYTHON_SCRIPT" ]; then + echo "Error: Python script $PYTHON_SCRIPT not found" + exit 1 +fi + +exec python3 "$PYTHON_SCRIPT" "$@" diff --git a/bin/runtool.py b/bin/runtool.py new file mode 100755 index 00000000..27e651e4 --- /dev/null +++ b/bin/runtool.py @@ -0,0 +1,372 @@ +#!/usr/bin/env python3 + +import os +import subprocess +import sys +from pathlib import Path + + +def get_script_dir(): + return Path(__file__).parent.resolve() + + +def get_lib_paths(): + script_dir = get_script_dir() + lutlang_lib = script_dir.parent / "verilog" / "lutlang.v" + celllang_lib = script_dir.parent / "verilog" / "celllang.v" + simlib = script_dir.parent / "verilog" / "simlib.v" + return { + "lutlang": str(lutlang_lib.resolve()), + "celllang": str(celllang_lib.resolve()), + "simlib": str(simlib.resolve()), + } + + +def check_dependencies(tool_name): + """Check if required tools are available""" + try: + subprocess.run(["which", "yosys"], check=True, stdout=subprocess.DEVNULL) + except subprocess.CalledProcessError: + print("yosys not found in PATH") + sys.exit(1) + + try: + subprocess.run(["which", tool_name], check=True, stdout=subprocess.DEVNULL) + except subprocess.CalledProcessError: + print(f"{tool_name} not found in PATH") + sys.exit(1) + + +def run_equiv_sh(input_file, output_file): + """Run equiv.sh script to check equivalence""" + try: + # Get the directory where equiv.sh should be located + script_dir = get_script_dir() + equiv_sh_path = script_dir.parent / "verilog" / "equiv.sh" + + # Ensure we're running from the directory containing the files + cwd = os.getcwd() + input_path = Path(input_file).resolve() + output_path = Path(output_file).resolve() + + # Run equiv.sh from the directory containing the files + result = subprocess.run( + [str(equiv_sh_path), str(input_path), str(output_path)], cwd=cwd + ) + if result.returncode != 0: + print(f"equiv.sh failed with exit code {result.returncode}") + return result.returncode + except FileNotFoundError: + print("equiv.sh not found in expected location") + return 1 + except Exception as e: + print(f"Error running equiv.sh: {e}") + return 1 + + +def generate_makefile_content(input_file, lib_path, tool_name, synth_target): + """Generate Makefile content for synthesis""" + content = [ + "SRCS=$(wildcard *.v)", + "# Set both Yosys and Vivado to use Ultrascale+ Arch", + "FAMILY=xcup", + "PART=xczu3eg-sbva484-1-i", + "# flatten design before synthesis, no clock buffers, no IO buffers, no carry logic, no MUXes", + "SYNTH_OPT=-flatten -noclkbuf -noiopad -nocarry -nowidelut -nosrl -ise", + "YOSYS=yosys # Yosys 0.33 (git sha1 2584903a060)", + "XILINX_VIVADO?=$(realpath $(dirname $(which vivado))/..)", + "VIVADO=$(XILINX_VIVADO)/bin/vivado", + "", + ".PHONY: all clean", + "", + f"all: {input_file}.{synth_target}", + "", + "clean:", + "\trm -f *.xil *.synth *.ys *.dot *.png", + "", + ] + + # Add synthesis rules + content.extend( + [ + "%.v.synth: %_synth.ys", + "\t+$(YOSYS) -s $<" + (" >> /dev/null" if "msynth" in sys.argv[0] else ""), + "", + "%.v.yxil: %_yxil.ys", + "\t+$(YOSYS) -s $<", + "", + "%.v.vxil: %_vxil.tcl", + "\t+$(VIVADO) -mode tcl -source $< -nolog -nojournal", + "", + "%.v.inline: %_inline.ys", + "\t+$(YOSYS) -s $<", + "", + "# This script synthesizes to LUTs", + "%_yxil.ys: %.v", + '\t@echo "read_verilog $<" > $@', + '\t@echo "synth_xilinx -family $(FAMILY) $(SYNTH_OPT)" >> $@', + '\t@echo "clean -purge" >> $@', + '\t@echo "splitnets -ports -format _" >> $@' + if "resynth" not in sys.argv[0] + else '\t@echo "splitnets -format _" >> $@', + '\t@echo "write_verilog -simple-lhs $<.yxil" >> $@', + "", + "# This script synthesizes to AND, NOR, XOR, INV, MUXes", + "%_synth.ys: %.v", + '\t@echo "read_verilog $<" > $@', + f'\t@echo "techmap -map {lib_path}" >> $@', + '\t@echo "clean -purge" >> $@', + '\t@echo "splitnets -format _" >> $@' + if "msynth" not in sys.argv[0] + else '\t@echo "splitnets -ports -format _" >> $@', + '\t@echo "write_verilog -simple-lhs $<.synth" >> $@', + "", + "%_vxil.tcl: %.v", + '\t@echo "add_files $<" > $@', + '\t@echo "synth_design -top $* -mode out_of_context -part $(PART)" >> $@', + '\t@echo "write_verilog -force $<.vxil" >> $@', + '\t@echo "quit" >> $@', + "", + "%_inline.ys: %.v", + f'\t@echo "read_verilog {get_lib_paths()["simlib"]}" > $@', + '\t@echo "read_verilog $<" >> $@', + '\t@echo "flatten" >> $@', + '\t@echo "clean -purge" >> $@', + '\t@echo "write_verilog -simple-lhs -noattr $<.inline" >> $@', + ] + ) + + return "\n".join(content) + + +def run_eqmap( + input_file, output_file, *args, synth_target="yxil", tool_name="eqmap_fpga" +): + """Main eqmap functionality""" + libs = get_lib_paths() + lib_path = libs["lutlang"] if tool_name == "eqmap_fpga" else libs["celllang"] + + if not os.path.isfile(input_file): + print("First argument must be the input file.") + print(f"Usage: {sys.argv[0]} [options]") + print("Check that file exists and it is the first argument") + sys.exit(1) + + check_dependencies(tool_name) + + mkfile_path = f"{input_file}.mk" + + # Generate Makefile + makefile_content = generate_makefile_content( + input_file, lib_path, tool_name, synth_target + ) + with open(mkfile_path, "w") as f: + f.write(makefile_content) + + # Run make + try: + subprocess.run( + ["make", "-f", mkfile_path, f"{input_file}.{synth_target}"], + stderr=subprocess.STDOUT, + ) + except subprocess.CalledProcessError as e: + print(f"Make failed with exit code {e.returncode}") + sys.exit(1) + + # Run the tool with output file parameter + tool_args = [tool_name, f"{input_file}.{synth_target}", output_file] + list(args) + try: + result = subprocess.run(tool_args) + if result.returncode != 0: + print(f"Tool {tool_name} failed with exit code {result.returncode}") + # Cleanup before exiting + try: + os.remove(f"{input_file}.{synth_target}") + os.remove(mkfile_path) + except OSError: + pass + sys.exit(result.returncode) + except FileNotFoundError: + print(f"Tool {tool_name} not found in PATH") + # Cleanup before exiting + try: + os.remove(f"{input_file}.{synth_target}") + os.remove(mkfile_path) + except OSError: + pass + sys.exit(1) + + # Run equiv.sh script + equiv_return_code = run_equiv_sh(input_file, output_file) + + # Cleanup + try: + os.remove(f"{input_file}.{synth_target}") + os.remove(mkfile_path) + except OSError: + pass + + # Exit with equiv.sh return code if it failed + if equiv_return_code != 0: + sys.exit(equiv_return_code) + + +def run_eqmap_vivado(input_file, output_file, *args): + """Run eqmap with Vivado backend""" + run_eqmap(input_file, output_file, *args, synth_target="vxil") + + +def run_fam(*args): + """Direct wrapper for eqmap_fpga""" + if len(args) < 2: + print("Usage: fam [options]") + sys.exit(1) + + try: + result = subprocess.run(["eqmap_fpga"] + list(args)) + if result.returncode == 0: + # Run equiv.sh if the tool succeeded + run_equiv_sh(args[0], args[1]) + else: + sys.exit(result.returncode) + except FileNotFoundError: + print("eqmap_fpga not found in PATH") + sys.exit(1) + + +def run_lvv(input_file, output_file, *args): + """Direct wrapper for eqmap - simplified to call run_eqmap directly""" + if input_file is None or output_file is None: + print("Usage: lvv [options]") + sys.exit(1) + + # Call run_eqmap directly with default parameters (eqmap uses yxil target) + run_eqmap(input_file, output_file, *args) + + +def run_lvv_vivado(input_file, output_file, *args): + """Direct wrapper for eqmap_vivado - simplified to call run_eqmap_vivado directly""" + if input_file is None or output_file is None: + print("Usage: lvv-vivado [options]") + sys.exit(1) + + # Call run_eqmap_vivado directly + run_eqmap_vivado(input_file, output_file, *args) + + +def run_msynth(input_file, output_file, *args): + """ASIC mapping functionality""" + run_eqmap( + input_file, output_file, *args, synth_target="synth", tool_name="eqmap_asic" + ) + + +def run_opt_verilog(*args): + """Optimization using parse-verilog and cargo""" + if "--help" in args: + try: + subprocess.run(["cargo", "run", "--quiet", "--release", "--", "--help"]) + except subprocess.CalledProcessError: + pass + return + + if len(args) < 2: + print("Usage: opt-verilog [options]") + sys.exit(1) + + input_file = args[0] + output_file = args[1] + other_args = args[2:] if len(args) > 2 else [] + + try: + # Build release version silently + subprocess.run(["cargo", "build", "--release"], stderr=subprocess.DEVNULL) + + # Run pipeline + with open(output_file, "w") as f: + parse_proc = subprocess.Popen( + ["parse-verilog", "--", input_file], stdout=subprocess.PIPE + ) + cargo_proc = subprocess.Popen( + ["cargo", "run", "--quiet", "--release", "--"] + list(other_args), + stdin=parse_proc.stdout, + stdout=f, + ) + if parse_proc.stdout: + parse_proc.stdout.close() + cargo_proc.communicate() + + # Run equiv.sh after successful completion + run_equiv_sh(input_file, output_file) + except FileNotFoundError as e: + print(f"Required tool not found: {e}") + sys.exit(1) + except subprocess.CalledProcessError as e: + print(f"Command failed with exit code {e.returncode}") + sys.exit(1) + + +def run_resynth(input_file, output_file, *args): + """FPGA resynthesis functionality""" + run_eqmap(input_file, output_file, *args, synth_target="synth") + + +def main(): + if len(sys.argv) < 2: + print("Usage: runtool [args...]") + print( + "Commands: eqmap, eqmap_vivado, fam, lvv, lvv-vivado, msynth, opt-verilog, resynth" + ) + sys.exit(1) + + command = sys.argv[1] + args = sys.argv[2:] + + # Map commands to functions + commands = { + "eqmap": lambda: ( + run_eqmap(*args) + if len(args) >= 2 + else print("Usage: eqmap [options]") + ), + "eqmap_vivado": lambda: ( + run_eqmap_vivado(*args) + if len(args) >= 2 + else print("Usage: eqmap_vivado [options]") + ), + "fam": lambda: run_fam(*args), + "lvv": lambda: ( + run_lvv(*args) + if len(args) >= 2 + else print("Usage: lvv [options]") + ), + "lvv-vivado": lambda: ( + run_lvv_vivado(*args) + if len(args) >= 2 + else print("Usage: lvv-vivado [options]") + ), + "msynth": lambda: ( + run_msynth(*args) + if len(args) >= 2 + else print("Usage: msynth [options]") + ), + "opt-verilog": lambda: run_opt_verilog(*args), + "resynth": lambda: ( + run_resynth(*args) + if len(args) >= 2 + else print("Usage: resynth [options]") + ), + } + + if command in commands: + commands[command]() + else: + print(f"Unknown command: {command}") + print( + "Available commands: eqmap, eqmap_vivado, fam, lvv, lvv-vivado, msynth, opt-verilog, resynth" + ) + sys.exit(1) + + +if __name__ == "__main__": + main() diff --git a/verilog/equiv.sh b/verilog/equiv.sh index b3ea3a1e..277522c1 100755 --- a/verilog/equiv.sh +++ b/verilog/equiv.sh @@ -24,6 +24,7 @@ echo "read_verilog $SIMLIB" > equiv.ys echo "read_verilog $2" >> equiv.ys echo "hierarchy -auto-top" >> equiv.ys echo "flatten" >> equiv.ys +echo "proc" >> equiv.ys echo "rename -top gold" >> equiv.ys echo "design -stash gold" >> equiv.ys @@ -31,6 +32,7 @@ echo "read_verilog $SIMLIB" >> equiv.ys echo "read_verilog $1" >> equiv.ys echo "hierarchy -auto-top" >> equiv.ys echo "flatten" >> equiv.ys +echo "proc" >> equiv.ys echo "rename -top rewritten" >> equiv.ys echo "design -stash rewritten" >> equiv.ys