docstr: Write the testbench file for io_stream (myproject_test.cpp and input/output .dat files)
  
  Args:
      model (ModelGraph): the hls4ml model.
docstr_tok: ["Write","the","testbench","file","for","io_stream","(","myproject_test.cpp","and","input\/output",".dat","files",")","Args",":","model","(","ModelGraph",")",":","the","hls4ml","model","."]
code: def write_testbench_stream(self, model):
      """Write the testbench file for io_stream (myproject_test.cpp and input/output .dat files)
  
      Args:
          model (ModelGraph): the hls4ml model.
      """
      if len(model.get_output_variables()) != 1:
          print(
              "WARNING:  The testbench only supports one output variable. Leaving empty testbench"
          )
          return
  
      outvar = model.get_output_variables()[0]
  
      model_inputs = model.get_input_variables()
      model_outputs = model.get_output_variables()
  
      filedir = os.path.dirname(os.path.abspath(__file__))
  
      if not os.path.exists(
          f"{model.config.get_output_dir()}/tb_data/"
      ):
          os.mkdir(f"{model.config.get_output_dir()}/tb_data/")
  
      input_data = model.config.get_config_value("InputData")
      output_predictions = model.config.get_config_value(
          "OutputPredictions"
      )
  
      if input_data:
          if input_data[-3:] == "dat":
              copyfile(
                  input_data,
                  f"{model.config.get_output_dir()}/tb_data/tb_input_features.dat",
              )
          else:
              self.__make_dat_file(
                  input_data,
                  f"{model.config.get_output_dir()}/tb_data/tb_input_features.dat",
              )
  
      if output_predictions:
          if output_predictions[-3:] == "dat":
              copyfile(
                  output_predictions,
                  f"{model.config.get_output_dir()}/tb_data/tb_output_predictions.dat",
              )
          else:
              self.__make_dat_file(
                  output_predictions,
                  f"{model.config.get_output_dir()}/tb_data/tb_output_predictions.dat",
              )
  
      f = open(
          os.path.join(
              filedir, "../templates/quartus/myproject_test_stream.cpp"
          )
      )
      fout = open(
          f"{model.config.get_output_dir()}/{model.config.get_project_name()}_test.cpp",
          "w",
      )
  
      model_brams = [
          var
          for var in model.get_weight_variables()
          if var.storage.lower() == "bram"
      ]
  
      for line in f.readlines():
          indent = " " * (len(line) - len(line.lstrip(" ")))
  
          if "myproject" in line:
              newline = line.replace(
                  "myproject", model.config.get_project_name()
              )
  
          elif "// hls-fpga-machine-learning insert bram" in line:
              newline = line
              for bram in model_brams:
                  newline += (
                      f'#include "firmware/weights/{bram.name}.h"\n'
                  )
  
          elif (
              "// hls-fpga-machine learning instantiate inputs and outputs"
              in line
          ):
              newline = line
              for inp in model_inputs:
                  newline += (
                      indent
                      + f"stream_in<{inp.type.name}> {inp.name}_input;\n"
                  )
              for out in model_outputs:
                  newline += (
                      indent
                      + f"stream_out<{out.type.name}> {out.name}_output;\n"
                  )
  
          # TODO - This is one-input specific (are multiple model inputs needed at all?)
          elif "// hls-fpga-machine-learning insert data" in line:
              newline = line
              c = 0
              for inp in model_inputs:
                  newline += (
                      indent + f"float vals_{c}[{inp.size_cpp()}]; \n"
                  )
                  newline += (
                      indent
                      + f"for (int j = 0 ; j < {inp.size_cpp()} ; j++) {{\n"
                  )
                  newline += (
                      indent + indent + f"vals_{c}[j] = in[j]; \n"
                  )
                  newline += indent + "}\n"
                  newline += (
                      indent
                      + f"nnet::convert_data<float, {inp.type.name}, {inp.size_cpp()}>(vals_{c}, {inp.name}_input);\n"
                  )
                  c += 1
  
          elif "// hls-fpga-machine-learning insert zero" in line:
              newline = line
              c = 0
              for inp in model_inputs:
                  newline += (
                      indent + f"float vals_{c}[{inp.size_cpp()}]; \n"
                  )
                  newline += (
                      indent
                      + f"for (int j = 0 ; j < {inp.size_cpp()} ; j++) {{\n"
                  )
                  newline += indent + indent + f"vals_{c}[j] = 0.0; \n"
                  newline += indent + "}\n"
                  newline += (
                      indent
                      + f"nnet::convert_data<float, {inp.type.name}, {inp.size_cpp()}>(vals_{c}, {inp.name}_input);\n"
                  )
                  c += 1
  
          elif (
              "// hls-fpga-machine-learning insert top-level-function"
              in line
          ):
              newline = line
              input_params = ", ".join(
                  [f"{i.name}_input" for i in model_inputs]
              )
              output_params = ", ".join(
                  [f"{o.name}_output" for o in model_outputs]
              )
              newline += (
                  indent
                  + f"ihc_hls_enqueue_noret(&{model.config.get_project_name()}, {input_params}, {output_params}"
              )
              if model_brams:
                  bram_vars = ",".join([b.name for b in model_brams])
                  newline += f", {bram_vars});\n"
              else:
                  newline += ");\n"
  
          elif "hls-fpga-machine-learning insert run" in line:
              newline = line
              newline += (
                  indent
                  + f"ihc_hls_component_run_all({model.config.get_project_name()});\n"
              )
  
          elif "// hls-fpga-machine-learning convert output" in line:
              newline = line
              newline += indent + f"float res[{outvar.size_cpp()}];\n"
              newline += (
                  indent
                  + "nnet::convert_data_back<{}, float, {}>({}_output, res);\n".format(
                      outvar.type.name, outvar.size_cpp(), outvar.name
                  )
              )
  
          elif "// hls-fpga-machine-learning insert tb-output" in line:
              newline += (
                  indent
                  + f"for(int i = 0; i < {outvar.size_cpp()}; i++) {{\n"
              )
              newline += indent + '  fout << res[i] << " ";\n'
              newline += indent + "}\n"
              newline += indent + "fout << std::endl;\n"
  
          elif "// hls-fpga-machine-learning print predictions" in line:
              newline = line
              newline += (
                  indent
                  + f"for(int i = 0; i < {outvar.size_cpp()}; i++) {{\n"
              )
              newline += (
                  indent
                  + '  std::cout << predictions[iteration][i] << " ";\n'
              )
              newline += indent + "}\n"
              newline += indent + "std::cout << std::endl;\n"
  
          elif "// hls-fpga-machine-learning print output" in line:
              newline = line
              newline += (
                  indent
                  + f"for(int i = 0; i < {outvar.size_cpp()}; i++) {{\n"
              )
              newline += indent + '  std::cout << res[i] << " "; \n'
              newline += indent + "} \n"
              newline += indent + "std::cout << std::endl; \n"
          else:
              newline = line
  
          fout.write(newline)
  
      f.close()
      fout.close()
  
imports: import glob
  import os
  import tarfile
  from collections import OrderedDict
  from shutil import copyfile, copytree, rmtree
  import numpy
  import yaml
  from hls4ml.backends import get_backend
  from hls4ml.model.layers import Conv1D, Conv2D, Conv2DBatchnorm, Dense
  from hls4ml.utils.fixed_point_utils import FixedPointEmulator, ceil_log2, uint_to_binary
  from hls4ml.writer.writers import Writer
label_desc: Use image node_id 12 for calling the QuartusWriter obj's underlying member method code with example usage: obj.write_testbench_stream(model) without return types