Skip to content

Commit

Permalink
parmys plugin for yosys frontend
Browse files Browse the repository at this point in the history
  • Loading branch information
poname committed Dec 6, 2022
1 parent 5889a1d commit 121e118
Show file tree
Hide file tree
Showing 14 changed files with 366 additions and 1 deletion.
1 change: 1 addition & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ jobs:
- {test: "vtr_reg_strong", cores: "16", options: "", cmake: "-DVTR_ASSERT_LEVEL=3", extra_pkgs: "libeigen3-dev"}
- {test: "vtr_reg_strong", cores: "16", options: "-skip_qor", cmake: "-DVTR_ASSERT_LEVEL=3 -DVTR_ENABLE_SANITIZE=ON", extra_pkgs: "libeigen3-dev"}
- {test: "vtr_reg_yosys", cores: "16", options: "", cmake: "-DWITH_YOSYS=ON -DYOSYS_SV_UHDM_PLUGIN=ON", extra_pkgs: ""}
- {test: "vtr_reg_yosys_parmys", cores: "16", options: "", cmake: "-DWITH_YOSYS=ON -DYOSYS_PARMYS_PLUGIN=ON", extra_pkgs: ""}
- {test: "vtr_reg_yosys_odin", cores: "16", options: "", cmake: "-DODIN_USE_YOSYS=ON -DYOSYS_SV_UHDM_PLUGIN=ON", extra_pkgs: ""}
- {test: "odin_tech_strong", cores: "16", options: "", cmake: "-DODIN_USE_YOSYS=ON", extra_pkgs: ""}
- {test: "odin_reg_strong", cores: "16", options: "", cmake: "", extra_pkgs: ""}
Expand Down
8 changes: 8 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ option(ODIN_SANITIZE "Enable building odin with sanitize flags" OFF)
option(WITH_YOSYS "Enable building Yosys" OFF)
option(ODIN_USE_YOSYS "Enable building Yosys" OFF)
option(YOSYS_SV_UHDM_PLUGIN "Enable building and installing Yosys SystemVerilog and UHDM plugins" OFF)
option(YOSYS_PARMYS_PLUGIN "Enable building and installing Parmys (Partial Mapper for Yosys) plugin" OFF)

set(VTR_VERSION_MAJOR 8)
set(VTR_VERSION_MINOR 1)
Expand Down Expand Up @@ -416,6 +417,13 @@ if(${YOSYS_SV_UHDM_PLUGIN})
endif()
endif()

# check YOSYS_PARMYS_PLUGIN flag
if(${YOSYS_PARMYS_PLUGIN})
if(NOT ${WITH_YOSYS})
message(SEND_ERROR "Using YOSYS_PARMYS_PLUGIN requires activating Yosys frontend. Please set WITH_YOSYS.")
endif()
endif()

#Add extra compilation flags to suppress warnings from some libraries/tools
# Note that target_compile_options() *appends* to the current compilation options of
# the specified target
Expand Down
7 changes: 7 additions & 0 deletions ODIN_II/regression_test/tools/run_yosys.sh
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ _YOSYS_EXEC="${VTR_DIR}/Yosys/bin/yosys"
_SURELOG_EXEC="${VTR_DIR}/Yosys/bin/surelog"
_UHDM_DUMP_EXEC="${VTR_DIR}/Yosys/bin/uhdm-dump"
_UHDM_HIER_EXEC="${VTR_DIR}/Yosys/bin/uhdm-hier"
_PARMYS_PLUGIN_EXEC="${VTR_DIR}/Yosys/share/yosys/plugins/parmys.so"
_INPUT_TYPE=""
_TEST_INPUT_LIST=()
_INPUT_LIST=()
Expand Down Expand Up @@ -461,6 +462,12 @@ function run_single_hdl() {
_exit_with_code "-1"
esac

if [ -f "${_PARMYS_PLUGIN_EXEC}" ]
then
export MAPPER="parmys";
else
export MAPPER="yosys";
fi

if [ -f "${OUTPUT_BLIF_PATH}/${TCL_BLIF_NAME}" ]; then
print_test_stat "E"
Expand Down
1 change: 1 addition & 0 deletions README.developers.md
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ will be triggered. The following tests are included in the workflow:
* [vtr_reg_nightly_test1-3](#vtr_reg_nightly_test1-3)
* [vtr_reg_strong](#vtr_reg_strong)
* vtr_reg_yosys
* vtr_reg_yosys_parmys
* vtr_reg_yosys_odin
* odin_tech_strong
* odin_reg_strong
Expand Down
37 changes: 37 additions & 0 deletions libs/EXTERNAL/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,40 @@ if(${ODIN_USE_YOSYS} OR ${WITH_YOSYS})
)
endif()

if(${YOSYS_PARMYS_PLUGIN})
set(YOSYS_DATDIR ${libyosys_BINARY_DIR}/share/yosys)
set(PARMYS_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/parmys-plugin)

ExternalProject_Add(parmys-plugin
PREFIX ""

GIT_REPOSITORY https://github.com/CAS-Atlantic/parmys-plugin.git
GIT_TAG v1.0
GIT_PROGRESS TRUE

# setting source, build and install directories
SOURCE_DIR "${PARMYS_SOURCE_DIR}"
BUILD_IN_SOURCE TRUE
INSTALL_DIR ""

INSTALL_COMMAND ""
CONFIGURE_COMMAND ""
BUILD_COMMAND ${MAKE_PROGRAM} -C ${PARMYS_SOURCE_DIR}
PATH=${libyosys_BINARY_DIR}/bin/:$ENV{PATH}
install -j${CMAKE_BUILD_PARALLEL_LEVEL}

# redirect logs to a logfile
LOG_BUILD ON
LOG_UPDATE ON
LOG_INSTALL ON
LOG_CONFIGURE ON
LOG_OUTPUT_ON_FAILURE ON

# dependency
DEPENDS yosys
)
endif()

# In addition to libyosys in the build folder, we copy the libyosys directory
# into a temporary folder in the VTR root, named Yosys, to have access to Yosys
# (plugins) execs for using in VTR scripts (similar to VPR/vpr or ODIN_II/odin_II)
Expand All @@ -115,6 +149,9 @@ if(${ODIN_USE_YOSYS} OR ${WITH_YOSYS})
if(${YOSYS_SV_UHDM_PLUGIN})
add_dependencies(vtr-yosys yosys-plugins)
endif()
if(${YOSYS_PARMYS_PLUGIN})
add_dependencies(vtr-yosys parmys-plugin)
endif()

endif()

Expand Down
81 changes: 81 additions & 0 deletions vtr_flow/misc/yosyslib/synthesis_parmys.tcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
yosys -import

plugin -i parmys
yosys -import

read_verilog -nomem2reg +/parmys/vtr_primitives.v
setattr -mod -set keep_hierarchy 1 single_port_ram
setattr -mod -set keep_hierarchy 1 dual_port_ram

puts "Using parmys as partial mapper"

parmys_arch -a QQQ

if {$env(PARSER) == "surelog" } {
puts "Using Yosys read_uhdm command"
plugin -i systemverilog
yosys -import
read_uhdm -debug XXX
} elseif {$env(PARSER) == "yosys-plugin" } {
puts "Using Yosys read_systemverilog command"
plugin -i systemverilog
yosys -import
read_systemverilog -debug XXX
} elseif {$env(PARSER) == "yosys" } {
puts "Using Yosys read_verilog command"
read_verilog -sv -nolatches XXX
} else {
error "Invalid PARSER"
}

# Check that there are no combinational loops
scc -select
select -assert-none %
select -clear

hierarchy -check -auto-top -purge_lib

opt_expr
opt_clean
check
opt -nodffe -nosdff
procs -norom
fsm
opt
wreduce
peepopt
opt_clean
share

opt -full
memory -nomap
flatten

opt -full

techmap -map +/parmys/adff2dff.v
techmap -map +/parmys/adffe2dff.v
techmap -map +/parmys/aldff2dff.v
techmap -map +/parmys/aldffe2dff.v

opt -full

#stat

parmys -a QQQ -nopass -c odin_config.xml

opt -full

techmap
opt -fast

dffunmap
opt -fast -noff

#autoname

tee -o /dev/stdout stat

hierarchy -check -auto-top -purge_lib

write_blif -true + vcc -false + gnd -undef + unconn -blackbox ZZZ
1 change: 1 addition & 0 deletions vtr_flow/scripts/python_libs/vtr/paths.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
yosys_exe_path = yosys_path / "bin" / "yosys"
yosys_lib_path = vtr_flow_path / "misc" / "yosyslib"
yosys_script_path = yosys_lib_path / "synthesis.tcl"
yosys_parmys_script_path = yosys_lib_path / "synthesis_parmys.tcl"

# ARCHFPGA paths
archfpga_path = root_path / "ArchFPGA"
Expand Down
90 changes: 89 additions & 1 deletion vtr_flow/scripts/python_libs/vtr/yosys/yosys.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from collections import OrderedDict
from pathlib import Path
import vtr
import xml.etree.ElementTree as ET

# supported input file type by Yosys
FILE_TYPES = {
Expand All @@ -31,6 +32,7 @@

YOSYS_PARSERS = ["yosys", "surelog", "yosys-plugin"]

YOSYS_MAPPERS = ["parmys", "yosys"]

def create_circuits_list(main_circuit, include_files):
"""Create a list of supported HDL files"""
Expand Down Expand Up @@ -68,6 +70,7 @@ def init_script_file(
memory_addr_width,
min_hard_mult_size,
min_hard_adder_size,
architecture_file_path,
):
"""initializing the raw yosys script file"""
# specify the input files type
Expand All @@ -89,6 +92,7 @@ def init_script_file(
"CCC": architecture_dsp_full_path,
"TTT": str(vtr.paths.yosys_lib_path),
"ZZZ": output_netlist,
"QQQ": architecture_file_path,
},
)

Expand All @@ -104,6 +108,56 @@ def init_script_file(
vtr.file_replace(yosys_spram_rename_full_path, {"PPP": memory_addr_width})
vtr.file_replace(yosys_dpram_rename_full_path, {"PPP": memory_addr_width})

# pylint: disable=too-many-arguments, too-many-locals
def init_config_file(
odin_config_full_path,
circuit_list,
architecture_file,
output_netlist,
odin_parser_arg,
memory_addr_width,
min_hard_mult_size,
min_hard_adder_size,
):
"""initializing the raw odin config file"""
# specify the input files type
file_extension = os.path.splitext(circuit_list[0])[-1]
if file_extension not in FILE_TYPES:
raise vtr.VtrError("Inavlid input file type '{}'".format(file_extension))
input_file_type = FILE_TYPES[file_extension]

# Check if the user specifically requested for the UHDM parser
if odin_parser_arg == "-u":
input_file_type = "uhdm"

# Update the config file
vtr.file_replace(
odin_config_full_path,
{
"YYY": architecture_file,
"TTT": input_file_type,
"ZZZ": output_netlist,
"PPP": memory_addr_width,
"MMM": min_hard_mult_size,
"AAA": min_hard_adder_size,
},
)

# loading the given config file
config_file = ET.parse(odin_config_full_path)
root = config_file.getroot()

# based on the base config file
verilog_files_tag = root.find("inputs")
# remove the template line XXX, verilog_files_tag [1] is a comment
verilog_files_tag.remove(verilog_files_tag[1])
for circuit in circuit_list:
verilog_file = ET.SubElement(verilog_files_tag, "input_path_and_name")
verilog_file.tail = "\n\n\t" if (circuit == circuit_list[-1]) else "\n\n\t\t"
verilog_file.text = circuit

# update the config file with new values
config_file.write(odin_config_full_path)

# pylint: disable=too-many-arguments, too-many-locals, too-many-statements, too-many-branches
def run(
Expand Down Expand Up @@ -175,7 +229,10 @@ def run(
yosys_exec = str(vtr.paths.yosys_exe_path)

if yosys_script is None:
yosys_base_script = str(vtr.paths.yosys_script_path)
if yosys_args["mapper"] == 'parmys':
yosys_base_script = str(vtr.paths.yosys_parmys_script_path)
else:
yosys_base_script = str(vtr.paths.yosys_script_path)
else:
yosys_base_script = str(Path(yosys_script).resolve())

Expand Down Expand Up @@ -210,6 +267,7 @@ def run(

write_arch_bb_exec = str(vtr.paths.write_arch_bb_exe_path)
architecture_dsp_full_path = str(vtr.paths.scripts_path / temp_dir / YOSYS_LIB_FILES["DSPBB"])
architecture_file_path = str(vtr.paths.scripts_path / architecture_file)

# executing write_arch_bb to extract the black box definitions of the given arch file
command_runner.run_system_command(
Expand Down Expand Up @@ -239,6 +297,25 @@ def run(
vtr.determine_memory_addr_width(str(architecture_file)),
min_hard_mult_size,
min_hard_adder_size,
architecture_file_path,
)

odin_base_config = str(vtr.paths.odin_cfg_path)

# Copy the config file
odin_config = "odin_config.xml"
odin_config_full_path = str(temp_dir / odin_config)
shutil.copyfile(odin_base_config, odin_config_full_path)

init_config_file(
odin_config_full_path,
circuit_list,
architecture_file.name,
output_netlist.name,
None,
vtr.determine_memory_addr_width(str(architecture_file)),
min_hard_mult_size,
min_hard_adder_size,
)

# set the parser
Expand All @@ -252,6 +329,17 @@ def run(
)
)

# set the partial mapper
if yosys_args["mapper"] in YOSYS_MAPPERS:
os.environ["MAPPER"] = yosys_args["mapper"]
del yosys_args["mapper"]
else:
raise vtr.VtrError(
"Invalid partial mapper is specified for Yosys, available parsers are [{}]".format(
" ".join(str(x) for x in YOSYS_MAPPERs)
)
)

cmd = [yosys_exec]

for arg, value in yosys_args.items():
Expand Down
7 changes: 7 additions & 0 deletions vtr_flow/scripts/run_vtr_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,12 @@ def vtr_command_argparser(prog=None):
+ "yosys-plugin (SystemVerilog)]. The script used the Yosys conventional Verilog"
+ " parser if this argument is not specified.",
)
yosys.add_argument(
"-mapper",
default="yosys",
dest="mapper",
help="Choose the partial mapper fot VTR flow with Yosys frontend between [parmys, yosys].",
)
#
# VPR arguments
#
Expand Down Expand Up @@ -733,6 +739,7 @@ def process_yosys_args(args):
"""
yosys_args = OrderedDict()
yosys_args["parser"] = args.parser
yosys_args["mapper"] = args.mapper

return yosys_args

Expand Down
Loading

0 comments on commit 121e118

Please sign in to comment.