import os
import re
import argparse
import csv

architectures = ['no_tensor_slice', \
                 'tensor_slice_5pct', \
                 'tensor_slice_10pct', \
                 'tensor_slice_15pct', \
                 'tensor_slice_20pct', \
                 'tensor_slice_25pct', \
                 'tensor_slice_30pct']

# ###############################################################
# Class for generating task directories, each containing 
# a config.txt file
# ###############################################################
class GenTaskDirs():
  #--------------------------
  #constructor
  #--------------------------
  def __init__(self):
    #members
    self.benchmarks = ''
    self.template = ''
    
    #method calls in order
    self.parse_args()
    self.generate_dirs()

  #--------------------------
  #parse command line args
  #--------------------------
  def parse_args(self):
    parser = argparse.ArgumentParser()
    parser.add_argument("-b",
                        "--benchmarks",
                        action='store',
                        default="list_of_benchmarks.aug_2021",
                        help="File containing list of benchmarks")
    parser.add_argument("-t",
                        "--template",
                        action='store',
                        default="template_config.aug_2021",
                        help="File containing the template config file")
    parser.add_argument("-o",
                        "--only_print",
                        action='store_true',
                        help="Only print. Do not execute commands")
    parser.add_argument("-e",
                        "--exp",
                        default=None,
                        action='store',
                        help="Exp name/number")
    parser.add_argument("-v",
                        "--vtr_flow_dir",
                        default="../..",
                        action='store',
                        help="Path of vtr_flow directory")
    args = parser.parse_args()
    print("Parsed arguments:", vars(args))
    self.benchmarks = args.benchmarks
    self.template = args.template
    self.only_print = args.only_print
    self.exp_name = args.exp
    self.vtr_flow_dir = args.vtr_flow_dir

  #--------------------------
  #generate task directories
  #--------------------------
  def generate_dirs(self):
    benchmarks = open(self.benchmarks, 'r')
    #the benchmarks file contains dir names. each dir_name contains 
    #information about the experiment
    for line in benchmarks:
      line = line.rstrip()
      #if the line is commented out, ignore it
      check_for_comment = re.search(r'^#', line)
      if check_for_comment is not None:
        continue

      print("Processing: " + line)

      #extract design name and type from the line
      info = re.search(r'(.*),(.*)', line)
      if info is not None:
        benchname = info.group(1)
        design_type = info.group(2) #ml or non_ml
      else:
        print("Unable to extract arch info from " + dirname)
        raise SystemExit(0)

      #identify the fpga arch
      for fpga_arch in architectures:
        # for exp4, we only want to run one arch - tensor slice with 25pct
        if self.exp_name == "exp4":
          if fpga_arch == "no_tensor_slice":
            arch_file = "k6FracN10LB_mem20K_complexDSP_customSB_22nm.no_tensor_slice.xml"
          elif fpga_arch == "tensor_slice_25pct":
            arch_file = "k6FracN10LB_mem20K_complexDSP_customSB_22nm.tensor_slice.25pct.xml"
          elif fpga_arch == "tensor_slice_30pct":
            arch_file = "k6FracN10LB_mem20K_complexDSP_customSB_22nm.tensor_slice.30pct.xml"
          else:
            continue
        # for exp3 (auto layout experiment), 
        # we only run for one arch with tensor slices (just pick the 15pct case)
        # and we use the special .auto_layout.xml arch files
        if self.exp_name == "exp3":
          if fpga_arch == "no_tensor_slice":
            arch_file = "k6FracN10LB_mem20K_complexDSP_customSB_22nm.no_tensor_slice.auto_layout.xml"
          elif fpga_arch == "tensor_slice_15pct":
            arch_file = "k6FracN10LB_mem20K_complexDSP_customSB_22nm.tensor_slice.auto_layout.xml"
          else:
            continue
        ## for exp2 (variable channel width experiment), 
        ## we only run for one arch with tensor slices (15pct) 
        #elif self.exp_name == "exp2":
        #  if fpga_arch == "no_tensor_slice":
        #    arch_file = "k6FracN10LB_mem20K_complexDSP_customSB_22nm.no_tensor_slice.xml"
        #  elif fpga_arch == "tensor_slice_15pct":
        #    arch_file = "k6FracN10LB_mem20K_complexDSP_customSB_22nm.tensor_slice.15pct.xml"
        #  else:
        #    continue
        else:
          if fpga_arch == "no_tensor_slice":
            arch_file = "k6FracN10LB_mem20K_complexDSP_customSB_22nm.no_tensor_slice.xml"
          elif fpga_arch == "tensor_slice_5pct":
            arch_file = "k6FracN10LB_mem20K_complexDSP_customSB_22nm.tensor_slice.5pct.xml"
          elif fpga_arch == "tensor_slice_10pct":
            arch_file = "k6FracN10LB_mem20K_complexDSP_customSB_22nm.tensor_slice.10pct.xml"
          elif fpga_arch == "tensor_slice_15pct":
            arch_file = "k6FracN10LB_mem20K_complexDSP_customSB_22nm.tensor_slice.15pct.xml"
          elif fpga_arch == "tensor_slice_20pct":
            arch_file = "k6FracN10LB_mem20K_complexDSP_customSB_22nm.tensor_slice.20pct.xml"
          elif fpga_arch == "tensor_slice_25pct":
            arch_file = "k6FracN10LB_mem20K_complexDSP_customSB_22nm.tensor_slice.25pct.xml"
          elif fpga_arch == "tensor_slice_30pct":
            arch_file = "k6FracN10LB_mem20K_complexDSP_customSB_22nm.tensor_slice.30pct.xml"
          else:
            print("Incorrect fpga arch {}".format(fpga_arch))
      
        #check it exists
        arch_dir = "arch/COFFE_22nm/arch_for_paper_jun_2021" 
        arch_file_path = self.vtr_flow_dir+"/"+arch_dir+"/"+ arch_file
        if not os.path.exists(arch_file_path):
          print("Arch file {} doesn't exist".format(arch_file_path))
          raise SystemExit(0)
      
        if design_type == "ml":
          if fpga_arch == "no_tensor_slice":
            design_file=benchname+".dsp.v"
          else: 
            design_file=benchname+".tensor_slice.v"
        else:
          design_file = benchname+".v"

        #for exp4, we only want to run .dsp.v files for ml bechmarks, even on arch with tensor slices
        if self.exp_name == "exp4" and design_type == "ml":
            design_file=benchname+".dsp.v"

        if design_type == "ml":
          design_dir = "benchmarks/verilog/design_for_paper_jun2021/"
        else:
          design_dir = "benchmarks/verilog"
        
        #special handling for exp5
        if self.exp_name == "exp5":
          if fpga_arch == "tensor_slice_5pct":
            design_file = re.sub(r'lstm', 'lstm_35_new', design_file)
          elif fpga_arch == "tensor_slice_10pct":
            design_file = re.sub(r'lstm', 'lstm_28_new', design_file)
          elif fpga_arch == "tensor_slice_15pct":
            design_file = re.sub(r'lstm', 'lstm_20_new', design_file)
          elif fpga_arch == "tensor_slice_20pct":
            design_file = re.sub(r'lstm', 'lstm_15_new', design_file)
          elif fpga_arch == "tensor_slice_25pct":
            design_file = re.sub(r'lstm', 'lstm_8_new', design_file)

        #check it exists
        design_file_path = self.vtr_flow_dir + "/" + design_dir + "/" + design_file
        if not os.path.exists(design_file_path):
          print("Design file {} doesn't exist".format(design_file_path))
          raise SystemExit(0)
        
        dirname = benchname + "." + fpga_arch

        #create the config file by replacing tags in the template
        config_filename = self.exp_name + "/" + dirname + "/config/config.txt"
        config_dirname  = self.exp_name + "/" + dirname + "/config"

        sdc_file = "../../../../../../../sdc/"+benchname+".sdc"
     
        print("config_filename: ", config_filename)
        print("config_dirname: ", config_dirname)
        print("design_file: ", design_file)
        print("arch_file: ", arch_file)
        print("")
        if not self.only_print:
          ret = os.system("mkdir -p " + config_dirname)
          if ret!=0:
            print("Directory " + config_dirname + " couldn't be created")

          try:
            config = open(config_filename, 'w')
          except:
            print("File " + config_filename + " couldn't be created")

          #add to git
          os.system("git add " + config_filename)

          template = open(self.template, 'r')
          for line in template:
            line = line.strip()
            line = re.sub(r'<design_dir>', design_dir, line)
            line = re.sub(r'<design_file>', design_file, line)
            line = re.sub(r'<arch_file>',   arch_file,   line)
            line = re.sub(r'<sdc_full_path>', sdc_file, line)
            #for exp2 (variable channel width experiment), we remove the <channel_width> part of the vpr args. for other experiments, we put in the switch to specify channel width of 300
            if self.exp_name != "exp2":
              line = re.sub(r'<channel_width>', "--route_chan_width 300", line)
            else:
              line = re.sub(r'<channel_width>', "", line)
            config.write(line)
            config.write("\n")
          config.close()
          print("Done")
    benchmarks.close()

# ###############################################################
# main()
# ###############################################################
if __name__ == "__main__":
  GenTaskDirs()


import os
import re
import argparse
import csv

architectures = ['no_tensor_slice', \
                 'tensor_slice_5pct', \
                 'tensor_slice_10pct', \
                 'tensor_slice_15pct', \
                 'tensor_slice_20pct', \
                 'tensor_slice_25pct', \
                 'tensor_slice_30pct']

# ###############################################################
# Class for generating task directories, each containing 
# a config.txt file
# ###############################################################
class GenTaskDirs():
  #--------------------------
  #constructor
  #--------------------------
  def __init__(self):
    #members
    self.benchmarks = ''
    self.template = ''
    
    #method calls in order
    self.parse_args()
    self.generate_dirs()

  #--------------------------
  #parse command line args
  #--------------------------
  def parse_args(self):
    parser = argparse.ArgumentParser()
    parser.add_argument("-b",
                        "--benchmarks",
                        action='store',
                        default="list_of_benchmarks.aug_2021",
                        help="File containing list of benchmarks")
    parser.add_argument("-t",
                        "--template",
                        action='store',
                        default="template_config.aug_2021",
                        help="File containing the template config file")
    parser.add_argument("-o",
                        "--only_print",
                        action='store_true',
                        help="Only print. Do not execute commands")
    parser.add_argument("-e",
                        "--exp",
                        default=None,
                        action='store',
                        help="Exp name/number")
    parser.add_argument("-v",
                        "--vtr_flow_dir",
                        default="../..",
                        action='store',
                        help="Path of vtr_flow directory")
    args = parser.parse_args()
    print("Parsed arguments:", vars(args))
    self.benchmarks = args.benchmarks
    self.template = args.template
    self.only_print = args.only_print
    self.exp_name = args.exp
    self.vtr_flow_dir = args.vtr_flow_dir

  #--------------------------
  #generate task directories
  #--------------------------
  def generate_dirs(self):
    benchmarks = open(self.benchmarks, 'r')
    #the benchmarks file contains dir names. each dir_name contains 
    #information about the experiment
    for line in benchmarks:
      line = line.rstrip()
      #if the line is commented out, ignore it
      check_for_comment = re.search(r'^#', line)
      if check_for_comment is not None:
        continue

      print("Processing: " + line)

      #extract design name and type from the line
      info = re.search(r'(.*),(.*)', line)
      if info is not None:
        benchname = info.group(1)
        design_type = info.group(2) #ml or non_ml
      else:
        print("Unable to extract arch info from " + dirname)
        raise SystemExit(0)

      #identify the fpga arch
      for fpga_arch in architectures:
        # for exp4, we only want to run one arch - tensor slice with 25pct
        if self.exp_name == "exp4":
          if fpga_arch == "no_tensor_slice":
            arch_file = "k6FracN10LB_mem20K_complexDSP_customSB_22nm.no_tensor_slice.xml"
          elif fpga_arch == "tensor_slice_25pct":
            arch_file = "k6FracN10LB_mem20K_complexDSP_customSB_22nm.tensor_slice.25pct.xml"
          elif fpga_arch == "tensor_slice_30pct":
            arch_file = "k6FracN10LB_mem20K_complexDSP_customSB_22nm.tensor_slice.30pct.xml"
          else:
            continue
        # for exp3 (auto layout experiment), 
        # we only run for one arch with tensor slices (just pick the 15pct case)
        # and we use the special .auto_layout.xml arch files
        if self.exp_name == "exp3":
          if fpga_arch == "no_tensor_slice":
            arch_file = "k6FracN10LB_mem20K_complexDSP_customSB_22nm.no_tensor_slice.auto_layout.xml"
          elif fpga_arch == "tensor_slice_15pct":
            arch_file = "k6FracN10LB_mem20K_complexDSP_customSB_22nm.tensor_slice.auto_layout.xml"
          else:
            continue
        ## for exp2 (variable channel width experiment), 
        ## we only run for one arch with tensor slices (15pct) 
        #elif self.exp_name == "exp2":
        #  if fpga_arch == "no_tensor_slice":
        #    arch_file = "k6FracN10LB_mem20K_complexDSP_customSB_22nm.no_tensor_slice.xml"
        #  elif fpga_arch == "tensor_slice_15pct":
        #    arch_file = "k6FracN10LB_mem20K_complexDSP_customSB_22nm.tensor_slice.15pct.xml"
        #  else:
        #    continue
        else:
          if fpga_arch == "no_tensor_slice":
            arch_file = "k6FracN10LB_mem20K_complexDSP_customSB_22nm.no_tensor_slice.xml"
          elif fpga_arch == "tensor_slice_5pct":
            arch_file = "k6FracN10LB_mem20K_complexDSP_customSB_22nm.tensor_slice.5pct.xml"
          elif fpga_arch == "tensor_slice_10pct":
            arch_file = "k6FracN10LB_mem20K_complexDSP_customSB_22nm.tensor_slice.10pct.xml"
          elif fpga_arch == "tensor_slice_15pct":
            arch_file = "k6FracN10LB_mem20K_complexDSP_customSB_22nm.tensor_slice.15pct.xml"
          elif fpga_arch == "tensor_slice_20pct":
            arch_file = "k6FracN10LB_mem20K_complexDSP_customSB_22nm.tensor_slice.20pct.xml"
          elif fpga_arch == "tensor_slice_25pct":
            arch_file = "k6FracN10LB_mem20K_complexDSP_customSB_22nm.tensor_slice.25pct.xml"
          elif fpga_arch == "tensor_slice_30pct":
            arch_file = "k6FracN10LB_mem20K_complexDSP_customSB_22nm.tensor_slice.30pct.xml"
          else:
            print("Incorrect fpga arch {}".format(fpga_arch))
      
        #check it exists
        arch_dir = "arch/COFFE_22nm/arch_for_paper_jun_2021" 
        arch_file_path = self.vtr_flow_dir+"/"+arch_dir+"/"+ arch_file
        if not os.path.exists(arch_file_path):
          print("Arch file {} doesn't exist".format(arch_file_path))
          raise SystemExit(0)
      
        if design_type == "ml":
          if fpga_arch == "no_tensor_slice":
            design_file=benchname+".dsp.v"
          else: 
            design_file=benchname+".tensor_slice.v"
        else:
          design_file = benchname+".v"

        #for exp4, we only want to run .dsp.v files for ml bechmarks, even on arch with tensor slices
        if self.exp_name == "exp4" and design_type == "ml":
            design_file=benchname+".dsp.v"

        if design_type == "ml":
          design_dir = "benchmarks/verilog/design_for_paper_jun2021/"
        else:
          design_dir = "benchmarks/verilog"
        
        #special handling for exp5
        if self.exp_name == "exp5":
          if fpga_arch == "tensor_slice_5pct":
            design_file = re.sub(r'lstm', 'lstm_35_new', design_file)
          elif fpga_arch == "tensor_slice_10pct":
            design_file = re.sub(r'lstm', 'lstm_28_new', design_file)
          elif fpga_arch == "tensor_slice_15pct":
            design_file = re.sub(r'lstm', 'lstm_20_new', design_file)
          elif fpga_arch == "tensor_slice_20pct":
            design_file = re.sub(r'lstm', 'lstm_15_new', design_file)
          elif fpga_arch == "tensor_slice_25pct":
            design_file = re.sub(r'lstm', 'lstm_8_new', design_file)

        #check it exists
        design_file_path = self.vtr_flow_dir + "/" + design_dir + "/" + design_file
        if not os.path.exists(design_file_path):
          print("Design file {} doesn't exist".format(design_file_path))
          raise SystemExit(0)
        
        dirname = benchname + "." + fpga_arch

        #create the config file by replacing tags in the template
        config_filename = self.exp_name + "/" + dirname + "/config/config.txt"
        config_dirname  = self.exp_name + "/" + dirname + "/config"

        sdc_file = "../../../../../../../sdc/"+benchname+".sdc"
     
        print("config_filename: ", config_filename)
        print("config_dirname: ", config_dirname)
        print("design_file: ", design_file)
        print("arch_file: ", arch_file)
        print("")
        if not self.only_print:
          ret = os.system("mkdir -p " + config_dirname)
          if ret!=0:
            print("Directory " + config_dirname + " couldn't be created")

          try:
            config = open(config_filename, 'w')
          except:
            print("File " + config_filename + " couldn't be created")

          #add to git
          os.system("git add " + config_filename)

          template = open(self.template, 'r')
          for line in template:
            line = line.strip()
            line = re.sub(r'<design_dir>', design_dir, line)
            line = re.sub(r'<design_file>', design_file, line)
            line = re.sub(r'<arch_file>',   arch_file,   line)
            line = re.sub(r'<sdc_full_path>', sdc_file, line)
            #for exp2 (variable channel width experiment), we remove the <channel_width> part of the vpr args. for other experiments, we put in the switch to specify channel width of 300
            if self.exp_name != "exp2":
              line = re.sub(r'<channel_width>', "--route_chan_width 300", line)
            else:
              line = re.sub(r'<channel_width>', "", line)
            config.write(line)
            config.write("\n")
          config.close()
          print("Done")
    benchmarks.close()

# ###############################################################
# main()
# ###############################################################
if __name__ == "__main__":
  GenTaskDirs()


# ############################################################### # Class for generating task directories, each containing # a config.txt file # ############################################################### #-------------------------- #constructor #-------------------------- #members #method calls in order #-------------------------- #parse command line args #-------------------------- #-------------------------- #generate task directories #-------------------------- #the benchmarks file contains dir names. each dir_name contains #information about the experiment #if the line is commented out, ignore it #', line) #extract design name and type from the line #ml or non_ml #identify the fpga arch # for exp4, we only want to run one arch - tensor slice with 25pct # for exp3 (auto layout experiment), # we only run for one arch with tensor slices (just pick the 15pct case) # and we use the special .auto_layout.xml arch files ## for exp2 (variable channel width experiment), ## we only run for one arch with tensor slices (15pct) #elif self.exp_name == "exp2": #  if fpga_arch == "no_tensor_slice": #    arch_file = "k6FracN10LB_mem20K_complexDSP_customSB_22nm.no_tensor_slice.xml" #  elif fpga_arch == "tensor_slice_15pct": #    arch_file = "k6FracN10LB_mem20K_complexDSP_customSB_22nm.tensor_slice.15pct.xml" #  else: #    continue #check it exists #for exp4, we only want to run .dsp.v files for ml bechmarks, even on arch with tensor slices #special handling for exp5 #check it exists #create the config file by replacing tags in the template #add to git #for exp2 (variable channel width experiment), we remove the <channel_width> part of the vpr args. for other experiments, we put in the switch to specify channel width of 300 # ############################################################### # main() # ###############################################################