Skip to content

Commit

Permalink
[AddStreams] Enable both rtlsim backends
Browse files Browse the repository at this point in the history
  • Loading branch information
auphelia committed Oct 25, 2024
1 parent 2437687 commit cc30757
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 43 deletions.
51 changes: 11 additions & 40 deletions src/finn/custom_op/fpgadataflow/hls/addstreams_hls.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
import finn.util.pyxsi_rpcclient as pyxsi_rpcclient
from finn.custom_op.fpgadataflow.addstreams import AddStreams
from finn.custom_op.fpgadataflow.hlsbackend import HLSBackend
from finn.util.basic import make_build_dir
from finn.util.data_packing import npy_to_rtlsim_input, rtlsim_output_to_npy


Expand Down Expand Up @@ -119,6 +118,7 @@ def execute_node(self, context, graph):
context[node.output[0]].shape == exp_oshape
), "cppsim did not produce expected output shape"
elif mode == "rtlsim":
rtlsim_backend = self.get_nodeattr("rtlsim_backend")
sim = self.get_rtlsim()
nbits = self.get_instream_width()
rtlsim_inp0 = npy_to_rtlsim_input(
Expand All @@ -127,10 +127,16 @@ def execute_node(self, context, graph):
rtlsim_inp1 = npy_to_rtlsim_input(
"{}/input_1.npy".format(code_gen_dir), export_idt, nbits
)
# super().reset_rtlsim(sim)
# super().toggle_clk(sim)
rtlsim_output = self.rtlsim(sim, rtlsim_inp0, rtlsim_inp1)
pyxsi_rpcclient.close_rtlsim(sim)
if rtlsim_backend == "pyverilator":
super().reset_rtlsim(sim)
super().toggle_clk(sim)
else:
pyxsi_rpcclient.reset_rtlsim(sim)
io_dict = {"inputs": {"in0": rtlsim_inp0, "in1": rtlsim_inp1}, "outputs": {"out": []}}
self.rtlsim_multi_io(sim, io_dict)
rtlsim_output = io_dict["outputs"]["out"]
if rtlsim_backend == "pyxsi":
pyxsi_rpcclient.close_rtlsim(sim)
odt = self.get_output_datatype()
target_bits = odt.bitwidth()
packed_bits = self.get_outstream_width()
Expand Down Expand Up @@ -254,38 +260,3 @@ def pragmas(self):
"#pragma HLS INTERFACE axis port=out_" + self.hls_sname()
)
self.code_gen_dict["$PRAGMAS$"].append("#pragma HLS INTERFACE ap_ctrl_none port=return")

def prepare_rtlsim(self):
verilog_files = self.get_all_verilog_filenames(abspath=True)
single_src_dir = make_build_dir("rtlsim_" + self.onnx_node.name + "_")

ret = pyxsi_rpcclient.compile_sim_obj(
self.get_verilog_top_module_name(), verilog_files, single_src_dir
)

# save generated lib filename in attribute
self.set_nodeattr("rtlsim_so", ret[0] + "/" + ret[1])

def get_rtlsim(self):
sim_xo_path = self.get_nodeattr("rtlsim_so")
sim_base, sim_rel = sim_xo_path.split("xsim.dir")
sim_rel = "xsim.dir" + sim_rel
tracefile = None
return pyxsi_rpcclient.load_sim_obj(sim_base, sim_rel, tracefile)

def rtlsim(self, sim, inp, inp2=None):
"""Runs the pyverilator simulation by passing the input values to the simulation,
toggle the clock and observing the execution time. Function contains also an
observation loop that can abort the simulation if no output value is produced
after 100 cycles."""

pyxsi_rpcclient.reset_rtlsim(sim)
io_dict = {"inputs": {"in0": inp, "in1": inp2}, "outputs": {"out": []}}
num_out_values = self.get_number_output_values()
sname = "_" + self.hls_sname() + "_"
total_cycle_count = pyxsi_rpcclient.rtlsim_multi_io(
sim, io_dict, num_out_values, sname=sname
)
self.set_nodeattr("cycles_rtlsim", total_cycle_count)

return io_dict["outputs"]["out"]
15 changes: 12 additions & 3 deletions tests/fpgadataflow/test_fpgadataflow_addstreams.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
from finn.transformation.fpgadataflow.specialize_layers import SpecializeLayers


def make_addstreams_modelwrapper(ch, pe, idt):
def make_addstreams_modelwrapper(ch, pe, idt, rtlsim_backend):
inp1 = helper.make_tensor_value_info("inp1", TensorProto.FLOAT, [1, ch])
inp2 = helper.make_tensor_value_info("inp2", TensorProto.FLOAT, [1, ch])
outp = helper.make_tensor_value_info("outp", TensorProto.FLOAT, [1, ch])
Expand All @@ -62,6 +62,7 @@ def make_addstreams_modelwrapper(ch, pe, idt):
PE=pe,
inputDataType=idt.name,
preferred_impl_style="hls",
rtlsim_backend=rtlsim_backend,
)
graph = helper.make_graph(
nodes=[addstreams_node],
Expand Down Expand Up @@ -91,20 +92,28 @@ def prepare_inputs(input1, input2):
@pytest.mark.parametrize("fold", [-1, 2, 1])
# execution mode
@pytest.mark.parametrize("exec_mode", ["cppsim", "rtlsim"])
# rtlsim_backend
@pytest.mark.parametrize("rtlsim_backend", ["pyverilator", "pyxsi"])
@pytest.mark.fpgadataflow
@pytest.mark.vivado
def test_fpgadataflow_addstreams(idt, ch, fold, exec_mode):
def test_fpgadataflow_addstreams(idt, ch, fold, exec_mode, rtlsim_backend):
if fold == -1:
pe = 1
else:
pe = max(1, ch // fold)
assert ch % pe == 0

if exec_mode == "cppsim" and rtlsim_backend == "pyxsi":
pytest.skip(
"""Skip combination of paramaters because rtlsim_backend
only influences rtlsim and not cppsim."""
)

# generate input data
x1 = gen_finn_dt_tensor(idt, (1, ch))
x2 = gen_finn_dt_tensor(idt, (1, ch))

model = make_addstreams_modelwrapper(ch, pe, idt)
model = make_addstreams_modelwrapper(ch, pe, idt, rtlsim_backend)

# prepare input data
input_dict = prepare_inputs(x1, x2)
Expand Down

0 comments on commit cc30757

Please sign in to comment.