Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pack RTL as IP #1115

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -927,11 +927,6 @@ def generate_hdl(self, model, fpgapart, clk):
shutil.copy2(os.environ["FINN_ROOT"] + "/finn-rtllib/swg/swg_common.sv", code_gen_dir)
shutil.copy2(os.environ["FINN_ROOT"] + "/finn-rtllib/swg/swg_pkg.sv", code_gen_dir)

# set ipgen_path and ip_path so that HLS-Synth transformation
# and stich_ip transformation do not complain
self.set_nodeattr("ipgen_path", code_gen_dir)
self.set_nodeattr("ip_path", code_gen_dir)

def prepare_rtlsim(self):
"""Creates a Verilator emulation library for the RTL code generated
for this node, sets the rtlsim_so attribute to its path and returns
Expand Down Expand Up @@ -964,31 +959,6 @@ def prepare_rtlsim(self):
self.set_nodeattr("rtlsim_so", sim.lib._name)
return sim

def code_generation_ipi(self):
"""Constructs and returns the TCL for node instantiation in Vivado IPI."""
code_gen_dir = self.get_nodeattr("code_gen_dir_ipgen")

sourcefiles = [
"swg_pkg.sv",
self.get_nodeattr("gen_top_module") + "_wrapper.v",
self.get_nodeattr("gen_top_module") + "_impl.sv",
"swg_common.sv",
]

if self.get_nodeattr("dynamic_mode"):
sourcefiles += [self.get_nodeattr("gen_top_module") + "_axilite.v"]

sourcefiles = [os.path.join(code_gen_dir, f) for f in sourcefiles]

cmd = []
for f in sourcefiles:
cmd += ["add_files -norecurse %s" % (f)]
cmd += [
"create_bd_cell -type module -reference %s %s"
% (self.get_nodeattr("gen_top_module"), self.onnx_node.name)
]
return cmd

def get_verilog_top_module_intf_names(self):
# Overload default HLSCustomOp implementation to add axilite control IF
"""Return a dict of names of input and output interfaces.
Expand Down
26 changes: 0 additions & 26 deletions src/finn/custom_op/fpgadataflow/rtl/fmpadding_rtl.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,10 +201,6 @@ def generate_hdl(self, model, fpgapart, clk):
sv_files = ["fmpadding_axi.sv", "fmpadding.sv", "axi2we.sv"]
for sv_file in sv_files:
shutil.copy(rtlsrc + "/" + sv_file, code_gen_dir)
# set ipgen_path and ip_path so that HLS-Synth transformation
# and stich_ip transformation do not complain
self.set_nodeattr("ipgen_path", code_gen_dir)
self.set_nodeattr("ip_path", code_gen_dir)

def prepare_rtlsim(self):
"""Creates a Verilator emulation library for the RTL code generated
Expand Down Expand Up @@ -235,25 +231,3 @@ def prepare_rtlsim(self):
# save generated lib filename in attribute
self.set_nodeattr("rtlsim_so", sim.lib._name)
return sim

def code_generation_ipi(self):
"""Constructs and returns the TCL for node instantiation in Vivado IPI."""
code_gen_dir = self.get_nodeattr("code_gen_dir_ipgen")

sourcefiles = [
"fmpadding_axi.sv",
"fmpadding.sv",
"axi2we.sv",
self.get_nodeattr("gen_top_module") + ".v",
]

sourcefiles = [os.path.join(code_gen_dir, f) for f in sourcefiles]

cmd = []
for f in sourcefiles:
cmd += ["add_files -norecurse %s" % (f)]
cmd += [
"create_bd_cell -type module -reference %s %s"
% (self.get_nodeattr("gen_top_module"), self.onnx_node.name)
]
return cmd
52 changes: 19 additions & 33 deletions src/finn/custom_op/fpgadataflow/rtl/matrixvectoractivation_rtl.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

import numpy as np
import os
import shutil
from pyverilator.util.axi_utils import reset_rtlsim, toggle_clk

from finn.custom_op.fpgadataflow.matrixvectoractivation import MVAU
Expand Down Expand Up @@ -145,38 +146,17 @@ def dsp_estimation(self, fpgapart):
mult_dsp = np.ceil(P / 4) * Q
return int(mult_dsp)

def code_generation_ipi(self):
return MVAU.code_generation_ipi(self)

def instantiate_ip(self, cmd):
# instantiate the RTL IP
code_gen_dir = self.get_nodeattr("code_gen_dir_ipgen")
rtllib_dir = os.path.join(os.environ["FINN_ROOT"], "finn-rtllib/mvu/")
sourcefiles = [
os.path.join(code_gen_dir, self.get_nodeattr("gen_top_module") + "_wrapper.v"),
rtllib_dir + "mvu_vvu_axi.sv",
rtllib_dir + "replay_buffer.sv",
rtllib_dir + "mvu_4sx4u.sv",
rtllib_dir + "mvu_vvu_8sx9_dsp58.sv",
rtllib_dir + "mvu_8sx8u_dsp48.sv",
]
for f in sourcefiles:
cmd.append("add_files -norecurse %s" % (f))
mem_mode = self.get_nodeattr("mem_mode")
if mem_mode == "internal_decoupled":
cmd.append(
"create_bd_cell -type hier -reference %s /%s/%s"
% (
self.get_nodeattr("gen_top_module"),
self.onnx_node.name,
self.onnx_node.name,
)
)
vlnv = self.get_nodeattr("ip_vlnv")
node_name = self.onnx_node.name
if self.get_nodeattr("mem_mode") == "internal_decoupled":
cmd.append("create_bd_cell -type ip -vlnv %s /%s/%s" % (vlnv, node_name, node_name))
else:
cmd.append(
"create_bd_cell -type hier -reference %s %s"
% (
self.get_nodeattr("gen_top_module"),
self.onnx_node.name,
)
)
cmd.append("create_bd_cell -type ip -vlnv %s %s" % (vlnv, node_name))

def _resolve_segment_len(self, clk):
# Insert pipeline registers in the DSP58 chain to meet target clock frequency
Expand Down Expand Up @@ -253,10 +233,16 @@ def generate_hdl(self, model, fpgapart, clk):
) as f:
f.write(template_wrapper.replace("$FORCE_BEHAVIORAL$", str(1)))

# set ipgen_path and ip_path so that HLS-Synth transformation
# and stich_ip transformation do not complain
self.set_nodeattr("ipgen_path", code_gen_dir)
self.set_nodeattr("ip_path", code_gen_dir)
rtllib_dir = os.path.join(os.environ["FINN_ROOT"], "finn-rtllib/mvu/")
sourcefiles = [
rtllib_dir + "mvu_vvu_axi.sv",
rtllib_dir + "replay_buffer.sv",
rtllib_dir + "mvu_4sx4u.sv",
rtllib_dir + "mvu_vvu_8sx9_dsp58.sv",
rtllib_dir + "mvu_8sx8u_dsp48.sv",
]
for f in sourcefiles:
shutil.copy(f, code_gen_dir)

def prepare_codegen_default(self, fpgapart, clk):
template_path = os.environ["FINN_ROOT"] + "/finn-rtllib/mvu/mvu_vvu_axi_wrapper.v"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,6 @@ def generate_hdl(self, model, fpgapart, clk):
sv_files = ["dwc_axi.sv", "dwc.sv"]
for sv_file in sv_files:
shutil.copy(rtlsrc + "/" + sv_file, code_gen_dir)
# set ipgen_path and ip_path so that HLS-Synth transformation
# and stich_ip transformation do not complain
self.set_nodeattr("ipgen_path", code_gen_dir)
self.set_nodeattr("ip_path", code_gen_dir)

def prepare_rtlsim(self):
"""Creates a Verilator emulation library for the RTL code generated
Expand Down Expand Up @@ -195,24 +191,3 @@ def prepare_rtlsim(self):
# save generated lib filename in attribute
self.set_nodeattr("rtlsim_so", sim.lib._name)
return sim

def code_generation_ipi(self):
"""Constructs and returns the TCL for node instantiation in Vivado IPI."""
code_gen_dir = self.get_nodeattr("code_gen_dir_ipgen")

sourcefiles = [
"dwc_axi.sv",
"dwc.sv",
self.get_nodeattr("gen_top_module") + ".v",
]

sourcefiles = [os.path.join(code_gen_dir, f) for f in sourcefiles]

cmd = []
for f in sourcefiles:
cmd += ["add_files -norecurse %s" % (f)]
cmd += [
"create_bd_cell -type module -reference %s %s"
% (self.get_nodeattr("gen_top_module"), self.onnx_node.name)
]
return cmd
22 changes: 1 addition & 21 deletions src/finn/custom_op/fpgadataflow/rtl/streamingfifo_rtl.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,6 @@ def generate_hdl(self, model, fpgapart, clk):
f.write(template)

shutil.copy(rtlsrc + "/Q_srl.v", code_gen_dir)
# set ipgen_path and ip_path so that HLS-Synth transformation
# and stich_ip transformation do not complain
self.set_nodeattr("ipgen_path", code_gen_dir)
self.set_nodeattr("ip_path", code_gen_dir)

def execute_node(self, context, graph):
mode = self.get_nodeattr("exec_mode")
Expand Down Expand Up @@ -177,23 +173,7 @@ def execute_node(self, context, graph):
def code_generation_ipi(self):
impl_style = self.get_nodeattr("impl_style")
if impl_style == "rtl":
code_gen_dir = self.get_nodeattr("code_gen_dir_ipgen")

sourcefiles = [
"Q_srl.v",
self.get_nodeattr("gen_top_module") + ".v",
]

sourcefiles = [os.path.join(code_gen_dir, f) for f in sourcefiles]

cmd = []
for f in sourcefiles:
cmd += ["add_files -norecurse %s" % (f)]
cmd += [
"create_bd_cell -type module -reference %s %s"
% (self.get_nodeattr("gen_top_module"), self.onnx_node.name)
]
return cmd
return RTLBackend.code_generation_ipi(self)
elif impl_style == "vivado":
cmd = []
node_name = self.onnx_node.name
Expand Down
33 changes: 1 addition & 32 deletions src/finn/custom_op/fpgadataflow/rtl/thresholding_rtl.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ def prepare_codegen_rtl_values(self, model):
with open(thresh_file, "w") as f:
for val in threshs:
f.write(val + "\n")
code_gen_dict["$THRESHOLDS_PATH$"] = ['"./%s_"' % self.onnx_node.name]
code_gen_dict["$THRESHOLDS_PATH$"] = [f'"{t_path}/{self.onnx_node.name}_"']

# Identify the module name
code_gen_dict["$MODULE_NAME_AXI_WRAPPER$"] = [
Expand Down Expand Up @@ -336,12 +336,6 @@ def generate_hdl(self, model, fpgapart, clk):
# dump filled-in template to destination directory for compilation
file_only_path = rtl_file_path.split("/")[-1]
self.dump_rtl_data(code_gen_dir, file_only_path, data)

# set ipgen_path and ip_path so that HLS-Synth transformation
# and stich_ip transformation do not complain
# i.e. during the HLSSynthIP() transformation
self.set_nodeattr("ipgen_path", code_gen_dir)
self.set_nodeattr("ip_path", code_gen_dir)
return

def prepare_rtlsim(self):
Expand Down Expand Up @@ -472,31 +466,6 @@ def execute_node(self, context, graph):
)
)

def code_generation_ipi(self):
"""Constructs and returns the TCL commands for node instantiation as an RTL
block."""
rtl_file_list = [
x.replace("thresholding_template_wrapper", self.get_nodeattr("gen_top_module"))
for x in self.get_rtl_file_list()
]
code_gen_dir = self.get_nodeattr("code_gen_dir_ipgen")
source_target = "./ip/verilog/rtl_ops/%s" % self.onnx_node.name
cmd = ["file mkdir %s" % source_target]

for rtl_file in rtl_file_list:
cmd.append(
"add_files -copy_to %s -norecurse %s"
% (source_target, os.path.join(code_gen_dir, rtl_file))
)

# Create an RTL block, not an IP core (-type ip)
cmd.append(
"create_bd_cell -type module -reference %s %s"
% (self.get_nodeattr("gen_top_module"), self.onnx_node.name)
)

return cmd

def get_verilog_top_module_intf_names(self):
intf_names = super().get_verilog_top_module_intf_names()
if self.get_nodeattr("runtime_writeable_weights") == 1:
Expand Down
53 changes: 19 additions & 34 deletions src/finn/custom_op/fpgadataflow/rtl/vectorvectoractivation_rtl.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

import numpy as np
import os
import shutil
from pyverilator.util.axi_utils import reset_rtlsim, toggle_clk
from qonnx.core.datatype import DataType

Expand Down Expand Up @@ -147,39 +148,17 @@ def dsp_estimation(self, fpgapart):
Q = self.get_nodeattr("SIMD")
return int(P * np.ceil(Q / 3))

def code_generation_ipi(self):
return VVAU.code_generation_ipi(self)

def instantiate_ip(self, cmd):
# instantiate the RTL IP
code_gen_dir = self.get_nodeattr("code_gen_dir_ipgen")
rtllib_dir = os.path.join(os.environ["FINN_ROOT"], "finn-rtllib/mvu/")
sourcefiles = [
os.path.join(code_gen_dir, self.get_nodeattr("gen_top_module") + "_wrapper.v"),
rtllib_dir + "mvu_vvu_axi.sv",
rtllib_dir + "replay_buffer.sv",
rtllib_dir + "mvu_4sx4u.sv",
rtllib_dir + "mvu_vvu_8sx9_dsp58.sv",
rtllib_dir + "mvu_8sx8u_dsp48.sv",
]
for f in sourcefiles:
cmd.append("add_files -norecurse %s" % (f))

mem_mode = self.get_nodeattr("mem_mode")
if mem_mode == "internal_decoupled":
cmd.append(
"create_bd_cell -type hier -reference %s /%s/%s"
% (
self.get_nodeattr("gen_top_module"),
self.onnx_node.name,
self.onnx_node.name,
)
)
vlnv = self.get_nodeattr("ip_vlnv")
node_name = self.onnx_node.name
if self.get_nodeattr("mem_mode") == "internal_decoupled":
cmd.append("create_bd_cell -type ip -vlnv %s /%s/%s" % (vlnv, node_name, node_name))
else:
cmd.append(
"create_bd_cell -type hier -reference %s %s"
% (
self.get_nodeattr("gen_top_module"),
self.onnx_node.name,
)
)
cmd.append("create_bd_cell -type ip -vlnv %s %s" % (vlnv, node_name))

def generate_hdl(self, model, fpgapart, clk):
# Generate params as part of IP preparation
Expand Down Expand Up @@ -216,10 +195,16 @@ def generate_hdl(self, model, fpgapart, clk):
) as f:
f.write(template_wrapper.replace("$FORCE_BEHAVIORAL$", str(1)))

# set ipgen_path and ip_path so that HLS-Synth transformation
# and stich_ip transformation do not complain
self.set_nodeattr("ipgen_path", code_gen_dir)
self.set_nodeattr("ip_path", code_gen_dir)
rtllib_dir = os.path.join(os.environ["FINN_ROOT"], "finn-rtllib/mvu/")
sourcefiles = [
rtllib_dir + "mvu_vvu_axi.sv",
rtllib_dir + "replay_buffer.sv",
rtllib_dir + "mvu_4sx4u.sv",
rtllib_dir + "mvu_vvu_8sx9_dsp58.sv",
rtllib_dir + "mvu_8sx8u_dsp48.sv",
]
for f in sourcefiles:
shutil.copy(f, code_gen_dir)

def _resolve_segment_len(self, clk):
# Insert pipeline registers in the DSP58 chain to meet target clock frequency
Expand Down
Loading