def set_board_name(self, board_name): """Sets the name of the board to use.""" if "board" not in self.project_tags.keys(): self.project_tags["board"] = "" self.project_tags["board"] = board_name self.board_dict = saputils.get_board_config(board_name)
def gen_script(self, tags = {}, buf = "", debug = False): """ Need to do a replace, but due to the {} in the script file it doesn't make sense to use the template """ board_dict = saputils.get_board_config(tags["board"]) fpga_pn = board_dict["fpga_part_number"] out_buf = "" if (len(buf.partition("set projName")[2]) > 0): temp_pre = buf.partition("set projName")[0] + "set projName" temp_buf = buf.partition("set projName")[2] out_buf = temp_pre + " " + tags["PROJECT_NAME"] + "\n" + temp_buf.partition("\n")[2] #add the device if (len(buf.partition("set device")[2]) > 0): temp_pre = buf.partition("set device")[0] + "set device" temp_buf = buf.partition("set device")[2] out_buf = temp_pre + " " + fpga_pn + "\n" + temp_buf.partition("\n")[2] return out_buf
def test_generate_arbitrators_simple(self): """the project file is supposed to generate one file""" #read in the configuration file config_file_name = os.getenv("SAPLIB_BASE") + "/example_project/arb_example.json" try: self.project.read_config_file(config_file_name, debug=self.dbg) except TypeError as err: print "Error reading JSON Config File: %s" % str(err) self.assertEqual(True, False) #read in the template #if there is an error an assertion will be raised self.project.read_template(self.project.project_tags["TEMPLATE"]) self.project.filegen.set_tags(self.project.project_tags) #get the clock rate from the constraint file board_dict = saputils.get_board_config("sycamore1") cfiles = board_dict["default_constraint_files"] self.project.project_tags["CLOCK_RATE"] = saputils.read_clock_rate(cfiles[0]) #generate the project directories and files self.project.project_tags["BASE_DIR"] = "~/sandbox/test_syc" saputils.create_dir(self.project.project_tags["BASE_DIR"]) #print "Parent dir: " + self.project.project_tags["BASE_DIR"] for key in self.project.template_tags["PROJECT_TEMPLATE"]["files"]: self.project.recursive_structure_generator( self.project.template_tags["PROJECT_TEMPLATE"]["files"], key, self.project.project_tags["BASE_DIR"]) arb_tags = saparbitrator.generate_arbitrator_tags(self.project.project_tags) self.project.project_tags["ARBITRATORS"] = arb_tags result = self.project.generate_arbitrators(debug = self.dbg) self.assertEqual(result, 1)
def test_get_board_config(self): """ gets the board configuration dictionary given the board name """ boardname = "sycamore1" board_dict = saputils.get_board_config(boardname, debug=False) self.assertEqual(board_dict["board_name"], "Sycamore 1")
def test_get_board_config(self): """ gets the board configuration dictionary given the board name """ boardname = "sycamore1" board_dict = saputils.get_board_config(boardname, debug = False) self.assertEqual(board_dict["board_name"], "Sycamore 1")
def gen_script(self, tags={}, buf="", debug=False): """Generate the project_defines.v""" if debug: print "" print "" print "" print "" print "" print "" print "" template = Template(buf) vendor_string = "VENDOR_FPGA" board_dict = saputils.get_board_config(tags["board"]) if board_dict["build_tool"] == "xilinx": #if (tags["BUILD_TOOL"] == "xilinx"): buf = template.safe_substitute(VENDOR_FPGA="VENDOR_XILINX") vendor_string = "VENDOR_XILINX" num_of_slaves = len(tags["SLAVES"]) num_of_memories = 0 if (debug): print "num of slaves: " + str(num_of_slaves) if ("MEMORY" in tags): print "num of memories: " + str(len(tags["MEMORY"])) if ("MEMORY" in tags): num_of_memories = len(tags["MEMORY"]) num_of_entities = str(num_of_slaves + num_of_memories) buf = template.substitute(PROJECT_NAME=tags["PROJECT_NAME"], NUMBER_OF_DEVICES=num_of_entities, VENDOR_FPGA=vendor_string, CLOCK_RATE=tags["CLOCK_RATE"]) if debug: print "generating clock rate" return buf
def test_generate_arbitrators_difficult(self): """the project calls for three arbitrators, but two are identical""" #read in the configuration file config_file_name = os.getenv( "SAPLIB_BASE") + "/example_project/arb_difficult_example.json" result = False try: self.project.read_config_file(config_file_name, debug=self.dbg) except TypeError as err: print "Error reading JSON Config File: %s" % str(err) self.assertEqual(True, False) #this will throw an exception if something failed self.project.read_template(self.project.project_tags["TEMPLATE"]) board_dict = saputils.get_board_config( self.project.project_tags["board"]) cfiles = board_dict["default_constraint_files"] self.project.filegen.set_tags(self.project.project_tags) #get the clock rate from the constraint file self.project.project_tags["CLOCK_RATE"] = saputils.read_clock_rate( cfiles[0]) #generate the project directories and files self.project.project_tags["BASE_DIR"] = "~/sandbox/test_syc" saputils.create_dir(self.project.project_tags["BASE_DIR"]) #print "Parent dir: " + self.project.project_tags["BASE_DIR"] for key in self.project.template_tags["PROJECT_TEMPLATE"]["files"]: self.project.recursive_structure_generator( self.project.template_tags["PROJECT_TEMPLATE"]["files"], key, self.project.project_tags["BASE_DIR"]) arb_tags = saparbitrator.generate_arbitrator_tags( self.project.project_tags) self.project.project_tags["ARBITRATORS"] = arb_tags result = self.project.generate_arbitrators(debug=self.dbg) self.assertEqual(result, 2)
def gen_script (self, tags={}, buf="", debug = False): """Generate the project_defines.v""" if debug: print "" print "" print "" print "" print "" print "" print "" template = Template(buf) vendor_string = "VENDOR_FPGA" board_dict = saputils.get_board_config(tags["board"]) if board_dict["build_tool"] == "xilinx": #if (tags["BUILD_TOOL"] == "xilinx"): buf = template.safe_substitute(VENDOR_FPGA = "VENDOR_XILINX") vendor_string = "VENDOR_XILINX" num_of_slaves = len(tags["SLAVES"]) num_of_memories = 0 if (debug): print "num of slaves: " + str(num_of_slaves) if ("MEMORY" in tags): print "num of memories: " + str(len(tags["MEMORY"])) if ("MEMORY" in tags): num_of_memories = len(tags["MEMORY"]) num_of_entities = str(num_of_slaves + num_of_memories) buf = template.substitute(PROJECT_NAME = tags["PROJECT_NAME"], NUMBER_OF_DEVICES=num_of_entities, VENDOR_FPGA=vendor_string, CLOCK_RATE=tags["CLOCK_RATE"]) if debug: print "generating clock rate" return buf
def test_generate_arbitrators_simple(self): """the project file is supposed to generate one file""" #read in the configuration file config_file_name = os.getenv( "SAPLIB_BASE") + "/example_project/arb_example.json" try: self.project.read_config_file(config_file_name, debug=self.dbg) except TypeError as err: print "Error reading JSON Config File: %s" % str(err) self.assertEqual(True, False) #read in the template #if there is an error an assertion will be raised self.project.read_template(self.project.project_tags["TEMPLATE"]) self.project.filegen.set_tags(self.project.project_tags) #get the clock rate from the constraint file board_dict = saputils.get_board_config("sycamore1") cfiles = board_dict["default_constraint_files"] self.project.project_tags["CLOCK_RATE"] = saputils.read_clock_rate( cfiles[0]) #generate the project directories and files self.project.project_tags["BASE_DIR"] = "~/sandbox/test_syc" saputils.create_dir(self.project.project_tags["BASE_DIR"]) #print "Parent dir: " + self.project.project_tags["BASE_DIR"] for key in self.project.template_tags["PROJECT_TEMPLATE"]["files"]: self.project.recursive_structure_generator( self.project.template_tags["PROJECT_TEMPLATE"]["files"], key, self.project.project_tags["BASE_DIR"]) arb_tags = saparbitrator.generate_arbitrator_tags( self.project.project_tags) self.project.project_tags["ARBITRATORS"] = arb_tags result = self.project.generate_arbitrators(debug=self.dbg) self.assertEqual(result, 1)
def test_generate_arbitrators_difficult(self): """the project calls for three arbitrators, but two are identical""" #read in the configuration file config_file_name = os.getenv("SAPLIB_BASE") + "/example_project/arb_difficult_example.json" result = False try: self.project.read_config_file(config_file_name, debug=self.dbg) except TypeError as err: print "Error reading JSON Config File: %s" % str(err) self.assertEqual(True, False) #this will throw an exception if something failed self.project.read_template(self.project.project_tags["TEMPLATE"]) board_dict = saputils.get_board_config(self.project.project_tags["board"]) cfiles = board_dict["default_constraint_files"] self.project.filegen.set_tags(self.project.project_tags) #get the clock rate from the constraint file self.project.project_tags["CLOCK_RATE"] = saputils.read_clock_rate(cfiles[0]) #generate the project directories and files self.project.project_tags["BASE_DIR"] = "~/sandbox/test_syc" saputils.create_dir(self.project.project_tags["BASE_DIR"]) #print "Parent dir: " + self.project.project_tags["BASE_DIR"] for key in self.project.template_tags["PROJECT_TEMPLATE"]["files"]: self.project.recursive_structure_generator( self.project.template_tags["PROJECT_TEMPLATE"]["files"], key, self.project.project_tags["BASE_DIR"]) arb_tags = saparbitrator.generate_arbitrator_tags(self.project.project_tags) self.project.project_tags["ARBITRATORS"] = arb_tags result = self.project.generate_arbitrators(debug = self.dbg) self.assertEqual(result, 2)
def generate_buffer(self, name="", index=-1, module_tags={}, mem_slave = False, io_module = False, debug = False): """Generate a buffer that attaches wishbone signals and return a buffer that can be used to generate the top module""" slave_name = name board_dict = saputils.get_board_config(self.tags["board"]) invert_reset = board_dict["invert_reset"] parameter_buffer = "" if (io_module == False): parameter_buffer = self.generate_parameters(name, module_tags, debug) out_buf = "" out_buf = "\t//" + name + "( " + module_tags["module"] + " )\n\n" out_buf = out_buf + "\t//wires\n" #if index == -1 then don't add an index #top_name will apply to all signals #go through each of hte module tags, and extrapolate the ports #generate the wires io_types = [ "input", "output", "inout" ] arb_index = -1 if ("ARBITRATORS" in self.tags.keys()): if (name in self.tags["ARBITRATORS"].keys()): arb_index = self.tags["ARBITRATORS"].keys().index(name) #add a prename to all the slaves pre_name = "" if (index != -1): if (arb_index != -1): pre_name = "arb" + str(arb_index) + "_" else: if mem_slave: pre_name += "sm" + str(index) + "_" else: pre_name += "s" + str(index) + "_" #XXX: For the slaves, I should just skip all the inout stuff, cause I don't ned wires for inout, they bind directly to the port #generate all the wires if (name != "io"): for io in io_types: for port in module_tags["ports"][io].keys(): pdict = module_tags["ports"][io][port] if ((len(name) > 0) and (index != -1)): wire = "" if (port == "clk" or port == "rst"): continue else: if (self.is_wishbone_port(port)): wire = pre_name + port else: wire = name + "_" + port if (wire in self.wires): continue self.wires.append(port) out_buf = out_buf + "\twire" #if the size is greater than one add it if (pdict["size"] > 1): out_buf = out_buf + "\t[" + str(pdict["max_val"]) + ":" + str(pdict["min_val"]) + "]\t\t" else: out_buf = out_buf + "\t\t\t\t" #add name and index if required if (len(name) > 0): if (port == "clk" or port == "rst"): out_buf += port else: if (self.is_wishbone_port(port)): out_buf += pre_name + port else: out_buf += name + "_" + port out_buf = out_buf + ";\n" out_buf = out_buf + "\n\n" #generate all wires for an IO module else: for io in io_types: for port in module_tags["ports"][io].keys(): pdict = module_tags["ports"][io][port] if (port == "clk" or port == "rst"): continue if (port in self.wires): continue self.wires.append(port) out_buf = out_buf + "\twire" #if the size if greater than one add it if (pdict["size"] > 1): out_buf = out_buf + "\t[" + str(pdict["max_val"]) + ":" + str(pdict["min_val"]) + "]\t\t" else: out_buf = out_buf + "\t\t\t" out_buf += port + ";\n" out_buf = out_buf + "\n\n" #Finished Generating the Wires #Generate the instantiation out_buf = out_buf + "\t" + module_tags["module"] + " " #check if there are parameters to be added out_buf += parameter_buffer out_buf += "\t" + name # if (index != -1): # out_buf = out_buf + str(index) out_buf = out_buf + "(\n" pindex = 0 last = len(module_tags["ports"]["input"].keys()) last = last + len(module_tags["ports"]["output"].keys()) last = last + len(module_tags["ports"]["inout"].keys()) #add the port assignments for io in io_types: for port in module_tags["ports"][io].keys(): pdict = module_tags["ports"][io][port] out_buf = out_buf + "\t\t." + port + "(" found_binding = False inout_binding = "" if (io == "inout"): if debug: print "found inout!: " + port bkeys = self.bindings.keys() for bkey in bkeys: bname = bkey.partition("[")[0] bname = bname.strip() if io_module: if debug: print "comparing %s with %s" % (bname, port) if (bname == port): if debug: print "found: " + bkey out_buf = out_buf + self.bindings[bkey]["port"] found_binding = True else: if debug: print "comparing %s with %s_%s" % (bname, name, port) if (bname == (name + "_" + port)): if debug: print "found: " + bkey out_buf = out_buf + self.bindings[bkey]["port"] found_binding = True if( not found_binding): #add name and index if required if ((len(name) > 0) and (index != -1)): if debug: print "found name and index %s %d" % (name, index) if (port.startswith(name)): out_buf = out_buf + name + str(index) + port.partition(name)[2] else: if (port == "clk" or port == "rst"): if (port == "rst"): if invert_reset: out_buf += "rst_n" else: out_buf += "rst" else: out_buf += port else: if (self.is_wishbone_port(port)): out_buf = out_buf + pre_name + port else: out_buf = out_buf + name + "_" + port else: if (port == "clk" or port == "rst"): if (port == "rst"): if invert_reset: out_buf += "rst_n" else: out_buf += "rst" else: out_buf += port else: if (self.is_wishbone_port(port)): out_buf = out_buf + pre_name + port else: if (not io_module): out_buf = out_buf + name + "_" + port else: out_buf = out_buf + port out_buf = out_buf + ")" pindex = pindex + 1 if (pindex == last): out_buf = out_buf + "\n" else: out_buf = out_buf + ",\n" out_buf = out_buf + "\t);" return out_buf
def generate_arbitrator_buffer(self, debug=False): result = "" board_dict = saputils.get_board_config(self.tags["board"]) invert_reset = board_dict["invert_reset"] #self.wires arbitrator_count = 0 if (not saparbitrator.is_arbitrator_required(self.tags)): return "" if debug: print "arbitration is required" result += "//Project Arbitrators\n\n" arb_tags = saparbitrator.generate_arbitrator_tags(self.tags) for i in range(0, len(arb_tags.keys())): arb_slave = arb_tags.keys()[i] master_count = 1 arb_name = "" if debug: print "found arbitrated slave: " + arb_slave result += "//" + arb_slave + " arbitrator\n\n" master_count += len(arb_tags[arb_slave].keys()) arb_name = "arb" + str(i) arb_module = "arbitrator_" + str(master_count) + "_masters" if debug: print "number of masters for this arbitrator: " + str( master_count) print "using: " + arb_module print "arbitrator name: " + arb_name #generate the wires for mi in range(0, master_count): wbm_name = "" if (mi == 0): #these wires are taken care of by the interconnect continue else: master_name = arb_tags[arb_slave].keys()[mi - 1] bus_name = arb_tags[arb_slave][master_name] wbm_name = master_name + "_" + bus_name #strobe wire = wbm_name + "_stb_o" if (not (wire in self.wires)): result += "\twire\t\t\t" + wire + ";\n" self.wires.append(wire) #cycle wire = wbm_name + "_cyc_o" if (not (wire in self.wires)): result += "\twire\t\t\t" + wire + ";\n" self.wires.append(wire) #write enable wire = wbm_name + "_we_o" if (not (wire in self.wires)): result += "\twire\t\t\t" + wire + ";\n" self.wires.append(wire) #select wire = wbm_name + "_sel_o" if (not (wire in self.wires)): result += "\twire\t[3:0]\t" + wire + ";\n" self.wires.append(wire) #in data wire = wbm_name + "_dat_o" if (not (wire in self.wires)): result += "\twire\t[31:0]\t" + wire + ";\n" self.wires.append(wire) #out data wire = wbm_name + "_dat_i" if (not (wire in self.wires)): result += "\twire\t[31:0]\t" + wire + ";\n" self.wires.append(wire) #address wire = wbm_name + "_adr_o" if (not (wire in self.wires)): result += "\twire\t[31:0]\t" + wire + ";\n" self.wires.append(wire) #acknowledge wire = wbm_name + "_ack_i" if (not (wire in self.wires)): result += "\twire\t\t\t" + wire + ";\n" self.wires.append(wire) #interrupt wire = wbm_name + "_int_i" if (not (wire in self.wires)): result += "\twire\t\t\t" + wire + ";\n" self.wires.append(wire) #generate arbitrator signals #strobe wire = arb_name + "_wbs_stb_i" if (not (wire in self.wires)): result += "\twire\t\t\t" + wire + ";\n" self.wires.append(wire) #cycle wire = arb_name + "_wbs_cyc_i" if (not (wire in self.wires)): result += "\twire\t\t\t" + wire + ";\n" self.wires.append(wire) #write enable wire = arb_name + "_wbs_we_i" if (not (wire in self.wires)): result += "\twire\t\t\t" + wire + ";\n" self.wires.append(wire) #select wire = arb_name + "_wbs_sel_i" if (not (wire in self.wires)): result += "\twire\t[3:0]\t" + wire + ";\n" self.wires.append(wire) #in data wire = arb_name + "_wbs_dat_i" if (not (wire in self.wires)): result += "\twire\t[31:0]\t" + wire + ";\n" self.wires.append(wire) #out data wire = arb_name + "_wbs_dat_o" if (not (wire in self.wires)): result += "\twire\t[31:0]\t" + wire + ";\n" self.wires.append(wire) #address wire = arb_name + "_wbs_adr_i" if (not (wire in self.wires)): result += "\twire\t[31:0]\t" + wire + ";\n" self.wires.append(wire) #acknowledge wire = arb_name + "_wbs_ack_o" if (not (wire in self.wires)): result += "\twire\t\t\t" + wire + ";\n" self.wires.append(wire) #interrupt wire = arb_name + "_wbs_int_o" if (not (wire in self.wires)): result += "\twire\t\t\t" + wire + ";\n" self.wires.append(wire) result += "\n\n" #finished generating the wires result += "\t" + arb_module + " " + arb_name + "(\n" result += "\t\t.clk(clk),\n" if invert_reset: result += "\t\t.rst(rst_n),\n" else: result += "\t\t.rst(rst),\n" result += "\n" result += "\t\t//masters\n" for mi in range(0, master_count): wbm_name = "" #last master is always from the interconnect #XXX: This should really be a parameter, but this will alow slaves to take over a peripheral if (mi == master_count - 1): if debug: print "mi: " + str(mi) on_periph_bus = False #in this case I need to use the wishbone interconnect #search for the index of the slave for i in range(0, len(self.tags["SLAVES"].keys())): name = self.tags["SLAVES"].keys()[i] if name == arb_slave: interconnect_index = i + 1 # +1 to account for DRT on_periph_bus = True wbm_name = "s" + str(interconnect_index) if debug: print "arb slave on peripheral bus" print "slave index: " + str( interconnect_index - 1) print "accounting for drt, actual bus index == " + str( interconnect_index) break #check mem bus if (not on_periph_bus): if ("MEMORY" in self.tags.keys()): #There is a memory bus, look in here for i in range(0, len(self.tags["MEMORY"].keys())): name = self.tags["MEMORY"].keys()[i] if name == arb_slave: mem_inc_index = i wbm_name = "sm" + str(i) if debug: print "arb slave on mem bus" print "slave index: " + str( mem_inc_index) break result += "\t\t.m" + str( mi) + "_stb_i(" + wbm_name + "_wbs_stb_i),\n" result += "\t\t.m" + str( mi) + "_cyc_i(" + wbm_name + "_wbs_cyc_i),\n" result += "\t\t.m" + str( mi) + "_we_i(" + wbm_name + "_wbs_we_i),\n" result += "\t\t.m" + str( mi) + "_sel_i(" + wbm_name + "_wbs_sel_i),\n" result += "\t\t.m" + str( mi) + "_dat_i(" + wbm_name + "_wbs_dat_i),\n" result += "\t\t.m" + str( mi) + "_adr_i(" + wbm_name + "_wbs_adr_i),\n" result += "\t\t.m" + str( mi) + "_dat_o(" + wbm_name + "_wbs_dat_o),\n" result += "\t\t.m" + str( mi) + "_ack_o(" + wbm_name + "_wbs_ack_o),\n" result += "\t\t.m" + str( mi) + "_int_o(" + wbm_name + "_wbs_int_o),\n" result += "\n\n" #not the last index else: if debug: print "mi: " + str(mi) master_name = arb_tags[arb_slave].keys()[mi] bus_name = arb_tags[arb_slave][master_name] wbm_name = master_name + "_" + bus_name result += "\t\t.m" + str( mi) + "_stb_i(" + wbm_name + "_stb_o),\n" result += "\t\t.m" + str( mi) + "_cyc_i(" + wbm_name + "_cyc_o),\n" result += "\t\t.m" + str( mi) + "_we_i(" + wbm_name + "_we_o),\n" result += "\t\t.m" + str( mi) + "_sel_i(" + wbm_name + "_sel_o),\n" result += "\t\t.m" + str( mi) + "_dat_i(" + wbm_name + "_dat_o),\n" result += "\t\t.m" + str( mi) + "_adr_i(" + wbm_name + "_adr_o),\n" result += "\t\t.m" + str( mi) + "_dat_o(" + wbm_name + "_dat_i),\n" result += "\t\t.m" + str( mi) + "_ack_o(" + wbm_name + "_ack_i),\n" result += "\t\t.m" + str( mi) + "_int_o(" + wbm_name + "_int_i),\n" result += "\n\n" result += "\t\t//slave\n" result += "\t\t.s_stb_o(" + arb_name + "_wbs_stb_i),\n" result += "\t\t.s_cyc_o(" + arb_name + "_wbs_cyc_i),\n" result += "\t\t.s_we_o(" + arb_name + "_wbs_we_i),\n" result += "\t\t.s_sel_o(" + arb_name + "_wbs_sel_i),\n" result += "\t\t.s_dat_o(" + arb_name + "_wbs_dat_i),\n" result += "\t\t.s_adr_o(" + arb_name + "_wbs_adr_i),\n" result += "\t\t.s_dat_i(" + arb_name + "_wbs_dat_o),\n" result += "\t\t.s_ack_i(" + arb_name + "_wbs_ack_o),\n" result += "\t\t.s_int_i(" + arb_name + "_wbs_int_o)\n" result += ");\n" return result
def generate_buffer(self, name="", index=-1, module_tags={}, mem_slave=False, io_module=False, debug=False): """Generate a buffer that attaches wishbone signals and return a buffer that can be used to generate the top module""" slave_name = name board_dict = saputils.get_board_config(self.tags["board"]) invert_reset = board_dict["invert_reset"] parameter_buffer = "" if (io_module == False): parameter_buffer = self.generate_parameters( name, module_tags, debug) out_buf = "" out_buf = "\t//" + name + "( " + module_tags["module"] + " )\n\n" out_buf = out_buf + "\t//wires\n" #if index == -1 then don't add an index #top_name will apply to all signals #go through each of hte module tags, and extrapolate the ports #generate the wires io_types = ["input", "output", "inout"] arb_index = -1 if ("ARBITRATORS" in self.tags.keys()): if (name in self.tags["ARBITRATORS"].keys()): arb_index = self.tags["ARBITRATORS"].keys().index(name) #add a prename to all the slaves pre_name = "" if (index != -1): if (arb_index != -1): pre_name = "arb" + str(arb_index) + "_" else: if mem_slave: pre_name += "sm" + str(index) + "_" else: pre_name += "s" + str(index) + "_" #XXX: For the slaves, I should just skip all the inout stuff, cause I don't ned wires for inout, they bind directly to the port #generate all the wires if (name != "io"): for io in io_types: for port in module_tags["ports"][io].keys(): pdict = module_tags["ports"][io][port] if ((len(name) > 0) and (index != -1)): wire = "" if (port == "clk" or port == "rst"): continue else: if (self.is_wishbone_port(port)): wire = pre_name + port else: wire = name + "_" + port if (wire in self.wires): continue self.wires.append(port) out_buf = out_buf + "\twire" #if the size is greater than one add it if (pdict["size"] > 1): out_buf = out_buf + "\t[" + str( pdict["max_val"]) + ":" + str( pdict["min_val"]) + "]\t\t" else: out_buf = out_buf + "\t\t\t\t" #add name and index if required if (len(name) > 0): if (port == "clk" or port == "rst"): out_buf += port else: if (self.is_wishbone_port(port)): out_buf += pre_name + port else: out_buf += name + "_" + port out_buf = out_buf + ";\n" out_buf = out_buf + "\n\n" #generate all wires for an IO module else: for io in io_types: for port in module_tags["ports"][io].keys(): pdict = module_tags["ports"][io][port] if (port == "clk" or port == "rst"): continue if (port in self.wires): continue self.wires.append(port) out_buf = out_buf + "\twire" #if the size if greater than one add it if (pdict["size"] > 1): out_buf = out_buf + "\t[" + str( pdict["max_val"]) + ":" + str( pdict["min_val"]) + "]\t\t" else: out_buf = out_buf + "\t\t\t" out_buf += port + ";\n" out_buf = out_buf + "\n\n" #Finished Generating the Wires #Generate the instantiation out_buf = out_buf + "\t" + module_tags["module"] + " " #check if there are parameters to be added out_buf += parameter_buffer out_buf += "\t" + name # if (index != -1): # out_buf = out_buf + str(index) out_buf = out_buf + "(\n" pindex = 0 last = len(module_tags["ports"]["input"].keys()) last = last + len(module_tags["ports"]["output"].keys()) last = last + len(module_tags["ports"]["inout"].keys()) #add the port assignments for io in io_types: for port in module_tags["ports"][io].keys(): pdict = module_tags["ports"][io][port] out_buf = out_buf + "\t\t." + port + "(" found_binding = False inout_binding = "" if (io == "inout"): if debug: print "found inout!: " + port bkeys = self.bindings.keys() for bkey in bkeys: bname = bkey.partition("[")[0] bname = bname.strip() if io_module: if debug: print "comparing %s with %s" % (bname, port) if (bname == port): if debug: print "found: " + bkey out_buf = out_buf + self.bindings[bkey]["port"] found_binding = True else: if debug: print "comparing %s with %s_%s" % (bname, name, port) if (bname == (name + "_" + port)): if debug: print "found: " + bkey out_buf = out_buf + self.bindings[bkey]["port"] found_binding = True if (not found_binding): #add name and index if required if ((len(name) > 0) and (index != -1)): if debug: print "found name and index %s %d" % (name, index) if (port.startswith(name)): out_buf = out_buf + name + str( index) + port.partition(name)[2] else: if (port == "clk" or port == "rst"): if (port == "rst"): if invert_reset: out_buf += "rst_n" else: out_buf += "rst" else: out_buf += port else: if (self.is_wishbone_port(port)): out_buf = out_buf + pre_name + port else: out_buf = out_buf + name + "_" + port else: if (port == "clk" or port == "rst"): if (port == "rst"): if invert_reset: out_buf += "rst_n" else: out_buf += "rst" else: out_buf += port else: if (self.is_wishbone_port(port)): out_buf = out_buf + pre_name + port else: if (not io_module): out_buf = out_buf + name + "_" + port else: out_buf = out_buf + port out_buf = out_buf + ")" pindex = pindex + 1 if (pindex == last): out_buf = out_buf + "\n" else: out_buf = out_buf + ",\n" out_buf = out_buf + "\t);" return out_buf
def gen_script(self, tags={}, buf="", debug=False): """Generate the Top Module""" board_dict = saputils.get_board_config(tags["board"]) invert_reset = board_dict["invert_reset"] en_mem_bus = False slave_list = tags["SLAVES"] self.internal_bindings = {} self.bindings = {} if "MEMORY" in tags: # if debug: # print "Found a memory bus" if (len(tags["MEMORY"]) > 0): if debug: print "found " + str(len( tags["MEMORY"])) + " memory devices" en_mem_bus = True num_slaves = len(slave_list) + 1 self.tags = tags #add the internal bindings self.internal_bindings = {} if "internal_bind" in self.tags.keys(): self.internal_bindings = self.tags["internal_bind"] #print "Internal bindings: %s" % str(self.internal_bindings) #add the global tags self.bindings = self.tags["bind"] #add the interface bindings directly if "bind" in self.tags["INTERFACE"]: for if_name in self.tags["INTERFACE"]["bind"]: self.bindings[if_name] = self.tags["INTERFACE"]["bind"][ if_name] #add each of the slave items to the binding #insert the names for slave_name in self.tags["SLAVES"]: if "bind" in self.tags["SLAVES"][slave_name]: for bind_name in self.tags["SLAVES"][slave_name]["bind"]: self.bindings[slave_name + "_" + bind_name] = self.tags[ "SLAVES"][slave_name]["bind"][bind_name] if "MEMORY" in self.tags: #add the slave bindings to the list for mem_name in self.tags["MEMORY"]: if "bind" in self.tags["MEMORY"][mem_name]: for bind_name in self.tags["MEMORY"][mem_name]["bind"]: self.bindings[mem_name + "_" + bind_name] = self.tags[ "MEMORY"][mem_name]["bind"][bind_name] if debug: print "found " + str(len(slave_list)) + " slaves" for slave in slave_list: print slave #remove all the ports from the possible wires self.add_ports_to_wires() template = Template(buf) header = "" port_buf = self.generate_ports() arb_buf = self.generate_arbitrator_buffer() wr_buf = "" wi_buf = "" wmi_buf = "" wm_buf = "" footer = "" header = "module top (\n" #header = header + "\tclk_in,\n" header = header + "\tclk,\n" header = header + "\trst,\n" for c_index in range(0, len(self.bindings.keys())): name = self.bindings.keys()[c_index] header = header + "\t" + self.bindings[name]["port"] if (c_index < len(self.bindings.keys()) - 1): header = header + "," header = header + "\n" header = header + ");" footer = "endmodule" #declare the ports #in the future utilize the constraints to generate the connections #declare the wires wr_buf = wr_buf + "\t//input handler signals\n" #wr_buf = wr_buf + "\tinput\t\tclk_in;\n" wr_buf = wr_buf + "\tinput\t\t\tclk;\n" #wr_buf = wr_buf + "\twire\t\tclk;\n" self.wires.append("clk") #self.wires.append("clk_in") wr_buf = wr_buf + "\tinput\t\t\trst;\n" self.wires.append("rst") if invert_reset: #print "found invert reset!" wr_buf += "\twire\t\t\trst_n;\n" self.wires.append("rst_n") wr_buf = wr_buf + "\twire\t[31:0]\tin_command;\n" self.wires.append("in_command") wr_buf = wr_buf + "\twire\t[31:0]\tin_address;\n" self.wires.append("in_address") wr_buf = wr_buf + "\twire\t[31:0]\tin_data;\n" self.wires.append("in_data") wr_buf = wr_buf + "\twire\t[27:0]\tin_data_count;\n" self.wires.append("in_data_count") wr_buf = wr_buf + "\twire\t\t\tih_ready;\n\n" self.wires.append("ih_ready") wr_buf = wr_buf + "\twire\t\t\tih_reset;\n\n" self.wires.append("ih_reset") wr_buf = wr_buf + "\t//output handler signals\n" wr_buf = wr_buf + "\twire\t[31:0]\tout_status;\n" self.wires.append("out_status") wr_buf = wr_buf + "\twire\t[31:0]\tout_address;\n" self.wires.append("out_address") wr_buf = wr_buf + "\twire\t[31:0]\tout_data;\n" self.wires.append("out_data") wr_buf = wr_buf + "\twire\t[27:0]\tout_data_count;\n" self.wires.append("out_data_count") wr_buf = wr_buf + "\twire\t\t\toh_ready;\n" self.wires.append("oh_ready") wr_buf = wr_buf + "\twire\t\t\toh_en;\n\n" self.wires.append("oh_en") wr_buf = wr_buf + "\t//master signals\n" wr_buf = wr_buf + "\twire\t\t\tmaster_ready;\n" self.wires.append("master_ready") wr_buf = wr_buf + "\twire\t\t\twbm_we_o;\n" self.wires.append("wbm_we_o") wr_buf = wr_buf + "\twire\t\t\twbm_cyc_o;\n" self.wires.append("wbm_cyc_o") wr_buf = wr_buf + "\twire\t\t\twbm_stb_o;\n" self.wires.append("wbm_stb_o") wr_buf = wr_buf + "\twire\t[3:0]\twbm_sel_o;\n" self.wires.append("wbm_sel_o") wr_buf = wr_buf + "\twire\t[31:0]\twbm_adr_o;\n" self.wires.append("wbm_adr_o") wr_buf = wr_buf + "\twire\t[31:0]\twbm_dat_i;\n" self.wires.append("wbm_dat_i") wr_buf = wr_buf + "\twire\t[31:0]\twbm_dat_o;\n" self.wires.append("wbm_dat_o") wr_buf = wr_buf + "\twire\t\t\twbm_ack_i;\n" self.wires.append("wbm_ack_i") wr_buf = wr_buf + "\twire\t\t\twbm_int_i;\n\n" self.wires.append("wbm_int_i") wr_buf = wr_buf + "\twire\t\t\tmem_we_o;\n" self.wires.append("mem_we_o") wr_buf = wr_buf + "\twire\t\t\tmem_cyc_o;\n" self.wires.append("mem_cyc_o") wr_buf = wr_buf + "\twire\t\t\tmem_stb_o;\n" self.wires.append("mem_stb_o") wr_buf = wr_buf + "\twire\t[3:0]\tmem_sel_o;\n" self.wires.append("mem_sel_o") wr_buf = wr_buf + "\twire\t[31:0]\tmem_adr_o;\n" self.wires.append("mem_adr_o") wr_buf = wr_buf + "\twire\t[31:0]\tmem_dat_i;\n" self.wires.append("mem_dat_i") wr_buf = wr_buf + "\twire\t[31:0]\tmem_dat_o;\n" self.wires.append("mem_dat_o") wr_buf = wr_buf + "\twire\t\t\tmem_ack_i;\n" self.wires.append("mem_ack_i") wr_buf = wr_buf + "\twire\t\t\tmem_int_i;\n" self.wires.append("mem_int_i") wr_buf = wr_buf + "\twire\t[31:0]\twbm_debug_out;\n\n" self.wires.append("wbm_debug_out") #put the in clock on the global buffer #wr_buf = wr_buf + "\t//add a global clock buffer to the input clock\n" #wr_buf = wr_buf + "\tIBUFG clk_ibuf(.I(clk_in), .O(clk));\n\n" wr_buf = wr_buf + "\t//slave signals\n\n" for i in range(0, num_slaves): wr_buf = wr_buf + "\t//slave " + str(i) + "\n" wr_buf = wr_buf + "\twire\t\t\ts" + str(i) + "_wbs_we_i;\n" self.wires.append("s" + str(i) + "_wbs_we_i") wr_buf = wr_buf + "\twire\t\t\ts" + str(i) + "_wbs_cyc_i;\n" self.wires.append("s" + str(i) + "_wbs_cyc_i") wr_buf = wr_buf + "\twire\t[31:0]\ts" + str(i) + "_wbs_dat_i;\n" self.wires.append("s" + str(i) + "_wbs_dat_i") wr_buf = wr_buf + "\twire\t[31:0]\ts" + str(i) + "_wbs_dat_o;\n" self.wires.append("s" + str(i) + "_wbs_dat_o") wr_buf = wr_buf + "\twire\t[31:0]\ts" + str(i) + "_wbs_adr_i;\n" self.wires.append("s" + str(i) + "_wbs_adr_i") wr_buf = wr_buf + "\twire\t\t\ts" + str(i) + "_wbs_stb_i;\n" self.wires.append("s" + str(i) + "_wbs_stb_i") wr_buf = wr_buf + "\twire\t[3:0]\ts" + str(i) + "_wbs_sel_i;\n" self.wires.append("s" + str(i) + "_wbs_sel_i") wr_buf = wr_buf + "\twire\t\t\ts" + str(i) + "_wbs_ack_o;\n" self.wires.append("s" + str(i) + "_wbs_ack_o") wr_buf = wr_buf + "\twire\t\t\ts" + str(i) + "_wbs_int_o;\n\n" self.wires.append("s" + str(i) + "_wbs_int_o") if (en_mem_bus): for i in range(0, len(tags["MEMORY"])): wr_buf = wr_buf + "\t//mem slave " + str(i) + "\n" wr_buf = wr_buf + "\twire\t\t\tsm" + str(i) + "_wbs_we_i;\n" self.wires.append("sm" + str(i) + "_wbs_we_i") wr_buf = wr_buf + "\twire\t\t\tsm" + str(i) + "_wbs_cyc_i;\n" self.wires.append("sm" + str(i) + "_wbs_cyc_i") wr_buf = wr_buf + "\twire\t[31:0]\tsm" + str( i) + "_wbs_dat_i;\n" self.wires.append("sm" + str(i) + "_wbs_dat_i") wr_buf = wr_buf + "\twire\t[31:0]\tsm" + str( i) + "_wbs_dat_o;\n" self.wires.append("sm" + str(i) + "_wbs_dat_o") wr_buf = wr_buf + "\twire\t[31:0]\tsm" + str( i) + "_wbs_adr_i;\n" self.wires.append("sm" + str(i) + "_wbs_adr_i") wr_buf = wr_buf + "\twire\t\t\tsm" + str(i) + "_wbs_stb_i;\n" self.wires.append("sm" + str(i) + "_wbs_stb_i") wr_buf = wr_buf + "\twire\t[3:0]\tsm" + str( i) + "_wbs_sel_i;\n" self.wires.append("sm" + str(i) + "_wbs_sel_i") wr_buf = wr_buf + "\twire\t\t\tsm" + str(i) + "_wbs_ack_o;\n" self.wires.append("sm" + str(i) + "_wbs_ack_o") wr_buf = wr_buf + "\twire\t\t\tsm" + str(i) + "_wbs_int_o;\n\n" self.wires.append("sm" + str(i) + "_wbs_int_o") if debug: print "wr_buf: \n" + wr_buf #generate the IO handler io_filename = tags["INTERFACE"]["filename"] absfilepath = saputils.find_rtl_file_location(io_filename) io_tags = saputils.get_module_tags(filename=absfilepath, bus="wishbone") io_buf = self.generate_buffer(name="io", module_tags=io_tags, io_module=True) #for the FPGA #constraints can be a dictionary with the mappings from device #to input/output/inout multidimensional values #this should just be file with text that I can pull in, it will always be #the same! #instantiate the connection interface #should this be another script that is clled within here? #can I extrapolate the required information directly from the #file? #interconnect wi_buf = "\twishbone_interconnect wi (\n" wi_buf = wi_buf + "\t\t.clk(clk),\n" if invert_reset: wi_buf = wi_buf + "\t\t.rst(rst_n),\n\n" else: wi_buf = wi_buf + "\t\t.rst(rst),\n\n" wi_buf = wi_buf + "\t\t//master\n" wi_buf = wi_buf + "\t\t.m_we_i(wbm_we_o),\n" wi_buf = wi_buf + "\t\t.m_cyc_i(wbm_cyc_o),\n" wi_buf = wi_buf + "\t\t.m_stb_i(wbm_stb_o),\n" wi_buf = wi_buf + "\t\t.m_sel_i(wbm_sel_o),\n" wi_buf = wi_buf + "\t\t.m_ack_o(wbm_ack_i),\n" wi_buf = wi_buf + "\t\t.m_dat_i(wbm_dat_o),\n" wi_buf = wi_buf + "\t\t.m_dat_o(wbm_dat_i),\n" wi_buf = wi_buf + "\t\t.m_adr_i(wbm_adr_o),\n" wi_buf = wi_buf + "\t\t.m_int_o(wbm_int_i),\n\n" for i in range(0, num_slaves): wi_buf = wi_buf + "\t\t//slave " + str(i) + "\n" wi_buf = wi_buf + "\t\t.s" + str(i) + "_we_o (s" + str( i) + "_wbs_we_i),\n" wi_buf = wi_buf + "\t\t.s" + str(i) + "_cyc_o(s" + str( i) + "_wbs_cyc_i),\n" wi_buf = wi_buf + "\t\t.s" + str(i) + "_stb_o(s" + str( i) + "_wbs_stb_i),\n" wi_buf = wi_buf + "\t\t.s" + str(i) + "_sel_o(s" + str( i) + "_wbs_sel_i),\n" wi_buf = wi_buf + "\t\t.s" + str(i) + "_ack_i(s" + str( i) + "_wbs_ack_o),\n" wi_buf = wi_buf + "\t\t.s" + str(i) + "_dat_o(s" + str( i) + "_wbs_dat_i),\n" wi_buf = wi_buf + "\t\t.s" + str(i) + "_dat_i(s" + str( i) + "_wbs_dat_o),\n" wi_buf = wi_buf + "\t\t.s" + str(i) + "_adr_o(s" + str( i) + "_wbs_adr_i),\n" wi_buf = wi_buf + "\t\t.s" + str(i) + "_int_i(s" + str( i) + "_wbs_int_o)" if (i < num_slaves - 1): wi_buf = wi_buf + ",\n" wi_buf = wi_buf + "\n\n" wi_buf = wi_buf + "\t);" if debug: print "wi_buf: \n" + wi_buf #memory interconnect if en_mem_bus: if debug: print "make the membus" wmi_buf = "\twishbone_mem_interconnect wmi (\n" wmi_buf = wmi_buf + "\t\t.clk(clk),\n" if invert_reset: wmi_buf = wmi_buf + "\t\t.rst(rst_n),\n\n" else: wmi_buf = wmi_buf + "\t\t.rst(rst),\n\n" wmi_buf = wmi_buf + "\t\t//master\n" wmi_buf = wmi_buf + "\t\t.m_we_i(mem_we_o),\n" wmi_buf = wmi_buf + "\t\t.m_cyc_i(mem_cyc_o),\n" wmi_buf = wmi_buf + "\t\t.m_stb_i(mem_stb_o),\n" wmi_buf = wmi_buf + "\t\t.m_sel_i(mem_sel_o),\n" wmi_buf = wmi_buf + "\t\t.m_ack_o(mem_ack_i),\n" wmi_buf = wmi_buf + "\t\t.m_dat_i(mem_dat_o),\n" wmi_buf = wmi_buf + "\t\t.m_dat_o(mem_dat_i),\n" wmi_buf = wmi_buf + "\t\t.m_adr_i(mem_adr_o),\n" wmi_buf = wmi_buf + "\t\t.m_int_o(mem_int_i),\n\n" num_mems = len(tags["MEMORY"]) for i in range(0, num_mems): wmi_buf = wmi_buf + "\t//mem slave " + str(i) + "\n" wmi_buf = wmi_buf + "\t\t.s" + str(i) + "_we_o(sm" + str( i) + "_wbs_we_i),\n" wmi_buf = wmi_buf + "\t\t.s" + str(i) + "_cyc_o(sm" + str( i) + "_wbs_cyc_i),\n" wmi_buf = wmi_buf + "\t\t.s" + str(i) + "_stb_o(sm" + str( i) + "_wbs_stb_i),\n" wmi_buf = wmi_buf + "\t\t.s" + str(i) + "_sel_o(sm" + str( i) + "_wbs_sel_i),\n" wmi_buf = wmi_buf + "\t\t.s" + str(i) + "_ack_i(sm" + str( i) + "_wbs_ack_o),\n" wmi_buf = wmi_buf + "\t\t.s" + str(i) + "_dat_o(sm" + str( i) + "_wbs_dat_i),\n" wmi_buf = wmi_buf + "\t\t.s" + str(i) + "_dat_i(sm" + str( i) + "_wbs_dat_o),\n" wmi_buf = wmi_buf + "\t\t.s" + str(i) + "_adr_o(sm" + str( i) + "_wbs_adr_i),\n" wmi_buf = wmi_buf + "\t\t.s" + str(i) + "_int_i(sm" + str( i) + "_wbs_int_o)" if ((num_mems > 0) and (i < num_mems - 1)): wmi_buf = wmi_buf + ",\n" wmi_buf = wmi_buf + "\n\n" wmi_buf = wmi_buf + "\t);" if debug: print "wmi_buf: \n" + wmi_buf #instantiate the io handler #instantiate the master wm_buf = wm_buf + "\twishbone_master wm (\n" wm_buf = wm_buf + "\t\t.clk(clk),\n" if invert_reset: wm_buf = wm_buf + "\t\t.rst(rst_n),\n\n" else: wm_buf = wm_buf + "\t\t.rst(rst),\n\n" wm_buf = wm_buf + "\t\t//input handler signals\n" wm_buf = wm_buf + "\t\t.in_ready(ih_ready),\n" wm_buf = wm_buf + "\t\t.ih_reset(ih_reset),\n" wm_buf = wm_buf + "\t\t.in_command(in_command),\n" wm_buf = wm_buf + "\t\t.in_address(in_address),\n" wm_buf = wm_buf + "\t\t.in_data(in_data),\n" wm_buf = wm_buf + "\t\t.in_data_count(in_data_count),\n\n" wm_buf = wm_buf + "\t\t//output handler signals\n" wm_buf = wm_buf + "\t\t.out_ready(oh_ready),\n" wm_buf = wm_buf + "\t\t.out_en(oh_en),\n" wm_buf = wm_buf + "\t\t.out_status(out_status),\n" wm_buf = wm_buf + "\t\t.out_address(out_address),\n" wm_buf = wm_buf + "\t\t.out_data(out_data),\n" wm_buf = wm_buf + "\t\t.out_data_count(out_data_count),\n" wm_buf = wm_buf + "\t\t.master_ready(master_ready),\n\n" wm_buf = wm_buf + "\t\t//interconnect signals\n" wm_buf = wm_buf + "\t\t.wb_adr_o(wbm_adr_o),\n" wm_buf = wm_buf + "\t\t.wb_dat_o(wbm_dat_o),\n" wm_buf = wm_buf + "\t\t.wb_dat_i(wbm_dat_i),\n" wm_buf = wm_buf + "\t\t.wb_stb_o(wbm_stb_o),\n" wm_buf = wm_buf + "\t\t.wb_cyc_o(wbm_cyc_o),\n" wm_buf = wm_buf + "\t\t.wb_we_o(wbm_we_o),\n" wm_buf = wm_buf + "\t\t.wb_msk_o(wbm_msk_o),\n" wm_buf = wm_buf + "\t\t.wb_sel_o(wbm_sel_o),\n" wm_buf = wm_buf + "\t\t.wb_ack_i(wbm_ack_i),\n" wm_buf = wm_buf + "\t\t.wb_int_i(wbm_int_i),\n\n" wm_buf = wm_buf + "\t\t//memory interconnect signals\n" wm_buf = wm_buf + "\t\t.mem_adr_o(mem_adr_o),\n" wm_buf = wm_buf + "\t\t.mem_dat_o(mem_dat_o),\n" wm_buf = wm_buf + "\t\t.mem_dat_i(mem_dat_i),\n" wm_buf = wm_buf + "\t\t.mem_stb_o(mem_stb_o),\n" wm_buf = wm_buf + "\t\t.mem_cyc_o(mem_cyc_o),\n" wm_buf = wm_buf + "\t\t.mem_we_o(mem_we_o),\n" wm_buf = wm_buf + "\t\t.mem_msk_o(mem_msk_o),\n" wm_buf = wm_buf + "\t\t.mem_sel_o(mem_sel_o),\n" wm_buf = wm_buf + "\t\t.mem_ack_i(mem_ack_i),\n" wm_buf = wm_buf + "\t\t.mem_int_i(mem_int_i),\n\n" wm_buf = wm_buf + "\t\t.debug_out(wbm_debug_out)\n\n" wm_buf = wm_buf + "\t);" if debug: print "wm_buf: \n" + wm_buf #Arbitrators #Slaves slave_index = 0 slave_buffer_list = [] absfilename = saputils.find_rtl_file_location("device_rom_table.v") slave_tags = saputils.get_module_tags(filename=absfilename, bus="wishbone") slave_buf = self.generate_buffer(name="drt", index=0, module_tags=slave_tags) slave_buffer_list.append(slave_buf) for i in range(0, len(tags["SLAVES"])): slave_name = tags["SLAVES"].keys()[i] slave = tags["SLAVES"][slave_name]["filename"] if debug: print "Slave name: " + slave absfilename = saputils.find_rtl_file_location(slave) slave_tags = saputils.get_module_tags(filename=absfilename, bus="wishbone") slave_buf = self.generate_buffer(name=slave_name, index=i + 1, module_tags=slave_tags) slave_buffer_list.append(slave_buf) #Memory devices mem_buf = "" mem_buffer_list = [] if en_mem_bus: #need to make all the memory devices for the memory bus mem_index = 0 mem_buffer_list = [] for i in range(0, len(tags["MEMORY"])): mem_name = tags["MEMORY"].keys()[i] filename = tags["MEMORY"][mem_name]["filename"] if debug: print "Mem device: " + mem_name + ", mem file: " + filename absfilename = saputils.find_rtl_file_location(filename) mem_tags = saputils.get_module_tags(filename=absfilename, bus="wishbone") mem_buf = self.generate_buffer(name=mem_name, index=i, module_tags=mem_tags, mem_slave=True) mem_buffer_list.append(mem_buf) buf_bind = "" buf_bind += "\t//assigns\n" #Generate the internal bindings if (len(self.internal_bindings.keys()) > 0): buf_bind += "\t//Internal Bindings\n" for key in self.internal_bindings.keys(): buf_bind += "\tassign\t%s\t=\t%s;\n" % ( key, self.internal_bindings[key]["signal"]) #Generate the external bindings if (len(self.bindings.keys()) > 0): buf_bind += "\t//Bindings to Ports\n" for key in self.bindings.keys(): if (self.bindings[key]["direction"] == "input"): buf_bind = buf_bind + "\tassign\t" + key + "\t=\t" + self.bindings[ key]["port"] + ";\n" elif (self.bindings[key]["direction"] == "output"): buf_bind = buf_bind + "\tassign\t" + self.bindings[key][ "port"] + "\t=\t" + key + ";\n" if invert_reset: buf_bind += "\tassign\trst_n\t\t=\t~rst;\n" top_buffer = header + "\n\n" top_buffer += port_buf + "\n\n" top_buffer += wr_buf + "\n\n" top_buffer += io_buf + "\n\n" top_buffer += wi_buf + "\n\n" top_buffer += wmi_buf + "\n\n" if (len(arb_buf) > 0): top_buffer += arb_buf + "\n\n" top_buffer += wm_buf + "\n\n" for slave_buf in slave_buffer_list: top_buffer = top_buffer + "\n\n" + slave_buf for mem_buf in mem_buffer_list: top_buffer = top_buffer + "\n\n" + mem_buf top_buffer = top_buffer + "\n\n" + buf_bind + "\n\n" + footer return top_buffer
def generate_arbitrator_buffer(self, debug = False): result = "" board_dict = saputils.get_board_config(self.tags["board"]) invert_reset = board_dict["invert_reset"] #self.wires arbitrator_count = 0 if (not saparbitrator.is_arbitrator_required(self.tags)): return "" if debug: print "arbitration is required" result += "//Project Arbitrators\n\n" arb_tags = saparbitrator.generate_arbitrator_tags(self.tags) for i in range (0, len(arb_tags.keys())): arb_slave = arb_tags.keys()[i] master_count = 1 arb_name = "" if debug: print "found arbitrated slave: " + arb_slave result += "//" + arb_slave + " arbitrator\n\n" master_count += len(arb_tags[arb_slave].keys()) arb_name = "arb" + str(i) arb_module = "arbitrator_" + str(master_count) + "_masters" if debug: print "number of masters for this arbitrator: " + str(master_count) print "using: " + arb_module print "arbitrator name: " + arb_name #generate the wires for mi in range (0, master_count): wbm_name = "" if (mi == 0): #these wires are taken care of by the interconnect continue else: master_name = arb_tags[arb_slave].keys()[mi - 1] bus_name = arb_tags[arb_slave][master_name] wbm_name = master_name + "_" + bus_name #strobe wire = wbm_name + "_stb_o" if (not (wire in self.wires)): result +="\twire\t\t\t" + wire + ";\n" self.wires.append(wire) #cycle wire = wbm_name + "_cyc_o" if (not (wire in self.wires)): result +="\twire\t\t\t" + wire + ";\n" self.wires.append(wire) #write enable wire = wbm_name + "_we_o" if (not (wire in self.wires)): result +="\twire\t\t\t" + wire + ";\n" self.wires.append(wire) #select wire = wbm_name + "_sel_o" if (not (wire in self.wires)): result +="\twire\t[3:0]\t" + wire + ";\n" self.wires.append(wire) #in data wire = wbm_name + "_dat_o" if (not (wire in self.wires)): result +="\twire\t[31:0]\t" + wire + ";\n" self.wires.append(wire) #out data wire = wbm_name + "_dat_i" if (not (wire in self.wires)): result +="\twire\t[31:0]\t" + wire + ";\n" self.wires.append(wire) #address wire = wbm_name + "_adr_o" if (not (wire in self.wires)): result +="\twire\t[31:0]\t" + wire + ";\n" self.wires.append(wire) #acknowledge wire = wbm_name + "_ack_i" if (not (wire in self.wires)): result +="\twire\t\t\t" + wire + ";\n" self.wires.append(wire) #interrupt wire = wbm_name + "_int_i" if (not (wire in self.wires)): result +="\twire\t\t\t" + wire + ";\n" self.wires.append(wire) #generate arbitrator signals #strobe wire = arb_name + "_wbs_stb_i" if (not (wire in self.wires)): result +="\twire\t\t\t" + wire + ";\n" self.wires.append(wire) #cycle wire = arb_name + "_wbs_cyc_i" if (not (wire in self.wires)): result +="\twire\t\t\t" + wire + ";\n" self.wires.append(wire) #write enable wire = arb_name + "_wbs_we_i" if (not (wire in self.wires)): result +="\twire\t\t\t" + wire + ";\n" self.wires.append(wire) #select wire = arb_name + "_wbs_sel_i" if (not (wire in self.wires)): result +="\twire\t[3:0]\t" + wire + ";\n" self.wires.append(wire) #in data wire = arb_name + "_wbs_dat_i" if (not (wire in self.wires)): result +="\twire\t[31:0]\t" + wire + ";\n" self.wires.append(wire) #out data wire = arb_name + "_wbs_dat_o" if (not (wire in self.wires)): result +="\twire\t[31:0]\t" + wire + ";\n" self.wires.append(wire) #address wire = arb_name + "_wbs_adr_i" if (not (wire in self.wires)): result +="\twire\t[31:0]\t" + wire + ";\n" self.wires.append(wire) #acknowledge wire = arb_name + "_wbs_ack_o" if (not (wire in self.wires)): result +="\twire\t\t\t" + wire + ";\n" self.wires.append(wire) #interrupt wire = arb_name + "_wbs_int_o" if (not (wire in self.wires)): result +="\twire\t\t\t" + wire + ";\n" self.wires.append(wire) result +="\n\n" #finished generating the wires result += "\t" + arb_module + " " + arb_name + "(\n" result += "\t\t.clk(clk),\n" if invert_reset: result += "\t\t.rst(rst_n),\n" else: result += "\t\t.rst(rst),\n" result += "\n" result += "\t\t//masters\n" for mi in range (0, master_count): wbm_name = "" #last master is always from the interconnect #XXX: This should really be a parameter, but this will alow slaves to take over a peripheral if (mi == master_count - 1): if debug: print "mi: " + str(mi) on_periph_bus = False #in this case I need to use the wishbone interconnect #search for the index of the slave for i in range (0, len(self.tags["SLAVES"].keys())): name = self.tags["SLAVES"].keys()[i] if name == arb_slave: interconnect_index = i + 1 # +1 to account for DRT on_periph_bus = True wbm_name = "s" + str(interconnect_index) if debug: print "arb slave on peripheral bus" print "slave index: " + str(interconnect_index - 1) print "accounting for drt, actual bus index == " + str(interconnect_index) break #check mem bus if (not on_periph_bus): if ("MEMORY" in self.tags.keys()): #There is a memory bus, look in here for i in range (0, len(self.tags["MEMORY"].keys())): name = self.tags["MEMORY"].keys()[i] if name == arb_slave: mem_inc_index = i wbm_name = "sm" + str(i) if debug: print "arb slave on mem bus" print "slave index: " + str(mem_inc_index) break result +="\t\t.m" + str(mi) + "_stb_i(" + wbm_name + "_wbs_stb_i),\n" result +="\t\t.m" + str(mi) + "_cyc_i(" + wbm_name + "_wbs_cyc_i),\n" result +="\t\t.m" + str(mi) + "_we_i(" + wbm_name + "_wbs_we_i),\n" result +="\t\t.m" + str(mi) + "_sel_i(" + wbm_name + "_wbs_sel_i),\n" result +="\t\t.m" + str(mi) + "_dat_i(" + wbm_name + "_wbs_dat_i),\n" result +="\t\t.m" + str(mi) + "_adr_i(" + wbm_name + "_wbs_adr_i),\n" result +="\t\t.m" + str(mi) + "_dat_o(" + wbm_name + "_wbs_dat_o),\n" result +="\t\t.m" + str(mi) + "_ack_o(" + wbm_name + "_wbs_ack_o),\n" result +="\t\t.m" + str(mi) + "_int_o(" + wbm_name + "_wbs_int_o),\n" result +="\n\n" #not the last index else: if debug: print "mi: " + str(mi) master_name = arb_tags[arb_slave].keys()[mi] bus_name = arb_tags[arb_slave][master_name] wbm_name = master_name + "_" + bus_name result +="\t\t.m" + str(mi) + "_stb_i(" + wbm_name + "_stb_o),\n" result +="\t\t.m" + str(mi) + "_cyc_i(" + wbm_name + "_cyc_o),\n" result +="\t\t.m" + str(mi) + "_we_i(" + wbm_name + "_we_o),\n" result +="\t\t.m" + str(mi) + "_sel_i(" + wbm_name + "_sel_o),\n" result +="\t\t.m" + str(mi) + "_dat_i(" + wbm_name + "_dat_o),\n" result +="\t\t.m" + str(mi) + "_adr_i(" + wbm_name + "_adr_o),\n" result +="\t\t.m" + str(mi) + "_dat_o(" + wbm_name + "_dat_i),\n" result +="\t\t.m" + str(mi) + "_ack_o(" + wbm_name + "_ack_i),\n" result +="\t\t.m" + str(mi) + "_int_o(" + wbm_name + "_int_i),\n" result +="\n\n" result += "\t\t//slave\n" result += "\t\t.s_stb_o(" + arb_name + "_wbs_stb_i),\n" result += "\t\t.s_cyc_o(" + arb_name + "_wbs_cyc_i),\n" result += "\t\t.s_we_o(" + arb_name + "_wbs_we_i),\n" result += "\t\t.s_sel_o(" + arb_name + "_wbs_sel_i),\n" result += "\t\t.s_dat_o(" + arb_name + "_wbs_dat_i),\n" result += "\t\t.s_adr_o(" + arb_name + "_wbs_adr_i),\n" result += "\t\t.s_dat_i(" + arb_name + "_wbs_dat_o),\n" result += "\t\t.s_ack_i(" + arb_name + "_wbs_ack_o),\n" result += "\t\t.s_int_i(" + arb_name + "_wbs_int_o)\n" result += ");\n" return result
def generate_project(self, config_file_name, debug=False): """Generate the folders and files for the project Using the project tags and template tags this function generates all the directories and files of the project. It will go through the template structure and determine what files need to be added and call either a generation script (in the case of \"top.v\") or simply copy the file over (in the case of a peripheral or memory module. Args: config_file_name: name of the JSON configuration file Return: True: Success False: Failure Raises: TypeError IOError SapError """ #reading the project config data into the the project tags #XXX: This should be changed to an exception begin raised and not a True False statement self.read_config_file(config_file_name) board_dict = saputils.get_board_config(self.project_tags["board"]) cfiles = [] pt = self.project_tags if "constraint_files" in pt.keys(): cfiles = pt["constraint_files"] #if the user didn't specify any constraint files #load the default if len(cfiles) == 0: cfiles = board_dict["default_constraint_files"] #extrapolate the bus template #XXX: Need to check all the constraint files self.project_tags["CLOCK_RATE"] = saputils.read_clock_rate(cfiles[0]) self.read_template(self.project_tags["TEMPLATE"]) #set all the tags within the filegen structure if debug: print "set all tags wihin filegen structure" self.filegen.set_tags(self.project_tags) #generate the project directories and files saputils.create_dir(self.project_tags["BASE_DIR"]) if debug: print "generated the first dir" #generate the arbitrator tags, this is important because the top #needs the arbitrator tags arb_tags = saparbitrator.generate_arbitrator_tags(self.project_tags, False) self.project_tags["ARBITRATORS"] = arb_tags #print "Parent dir: " + self.project_tags["BASE_DIR"] for key in self.template_tags["PROJECT_TEMPLATE"]["files"]: self.recursive_structure_generator( self.template_tags["PROJECT_TEMPLATE"]["files"], key, self.project_tags["BASE_DIR"]) if debug: print "generating project directories finished" if debug: print "generate the arbitrators" self.generate_arbitrators() #Generate all the slaves for slave in self.project_tags["SLAVES"]: fdict = {"location":""} file_dest = self.project_tags["BASE_DIR"] + "/rtl/bus/slave" fn = self.project_tags["SLAVES"][slave]["filename"] try: self.filegen.process_file(filename = fn, file_dict = fdict, directory=file_dest, debug=debug) except ModuleFactoryError as err: print "ModuleFactoryError while generating a slave: %s" % str(err) #each slave if ("MEMORY" in self.project_tags): for mem in self.project_tags["MEMORY"]: fdict = {"location":""} file_dest = self.project_tags["BASE_DIR"] + "/rtl/bus/slave" fn = self.project_tags["MEMORY"][mem]["filename"] try: self.filegen.process_file(filename = fn, file_dict = fdict, directory = file_dest) except ModuleFactoryError as err: print "ModuleFactoryError while generating a memory slave: %s" % str(err) #Copy the user specified constraint files to the constraints directory for constraint_fname in cfiles: sap_abs_base = os.getenv("SAPLIB_BASE") abs_proj_base = saputils.resolve_linux_path(self.project_tags["BASE_DIR"]) constraint_path = self.get_constraint_path(constraint_fname) if (len(constraint_path) == 0): print "Couldn't find constraint: " + constraint_fname + ", searched in current directory and " + sap_abs_base + " /hdl/" + self.project_tags["board"] continue shutil.copy (constraint_path, abs_proj_base + "/constraints/" + constraint_fname) #Generate the IO handler interface_filename = self.project_tags["INTERFACE"]["filename"] fdict = {"location":""} file_dest = self.project_tags["BASE_DIR"] + "/rtl/bus/interface" result = self.filegen.process_file(filename = interface_filename, file_dict=fdict , directory=file_dest) if debug: print "copy over the dependencies..." print "verilog files: " for f in self.filegen.verilog_file_list: print f print "dependent files: " for d in self.filegen.verilog_dependency_list: fdict = {"location":""} file_dest = self.project_tags["BASE_DIR"] + "/dependencies" result = self.filegen.process_file(filename = d, file_dict = fdict, directory = file_dest) if debug: print d return True
def gen_script (self, tags = {}, buf = "", debug = False): """Generate the Top Module""" board_dict = saputils.get_board_config(tags["board"]) invert_reset = board_dict["invert_reset"] en_mem_bus = False slave_list = tags["SLAVES"] self.internal_bindings = {} self.bindings = {} if "MEMORY" in tags: # if debug: # print "Found a memory bus" if (len(tags["MEMORY"]) > 0): if debug: print "found " + str(len(tags["MEMORY"])) + " memory devices" en_mem_bus = True num_slaves = len(slave_list) + 1 self.tags = tags #add the internal bindings self.internal_bindings = {} if "internal_bind" in self.tags.keys(): self.internal_bindings = self.tags["internal_bind"] #print "Internal bindings: %s" % str(self.internal_bindings) #add the global tags self.bindings = self.tags["bind"] #add the interface bindings directly if "bind" in self.tags["INTERFACE"]: for if_name in self.tags["INTERFACE"]["bind"]: self.bindings[if_name] = self.tags["INTERFACE"]["bind"][if_name] #add each of the slave items to the binding #insert the names for slave_name in self.tags["SLAVES"]: if "bind" in self.tags["SLAVES"][slave_name]: for bind_name in self.tags["SLAVES"][slave_name]["bind"]: self.bindings[slave_name + "_" + bind_name] = self.tags["SLAVES"][slave_name]["bind"][bind_name] if "MEMORY" in self.tags: #add the slave bindings to the list for mem_name in self.tags["MEMORY"]: if "bind" in self.tags["MEMORY"][mem_name]: for bind_name in self.tags["MEMORY"][mem_name]["bind"]: self.bindings[mem_name + "_" + bind_name] = self.tags["MEMORY"][mem_name]["bind"][bind_name] if debug: print "found " + str(len(slave_list)) + " slaves" for slave in slave_list: print slave #remove all the ports from the possible wires self.add_ports_to_wires() template = Template(buf) header = "" port_buf = self.generate_ports() arb_buf = self.generate_arbitrator_buffer() wr_buf = "" wi_buf = "" wmi_buf = "" wm_buf = "" footer = "" header = "module top (\n" #header = header + "\tclk_in,\n" header = header + "\tclk,\n" header = header + "\trst,\n" for c_index in range(0, len(self.bindings.keys())): name = self.bindings.keys()[c_index] header = header + "\t" + self.bindings[name]["port"] if (c_index < len(self.bindings.keys()) - 1): header = header + "," header = header + "\n" header = header + ");" footer = "endmodule" #declare the ports #in the future utilize the constraints to generate the connections #declare the wires wr_buf = wr_buf + "\t//input handler signals\n" #wr_buf = wr_buf + "\tinput\t\tclk_in;\n" wr_buf = wr_buf + "\tinput\t\t\tclk;\n" #wr_buf = wr_buf + "\twire\t\tclk;\n" self.wires.append("clk") #self.wires.append("clk_in") wr_buf = wr_buf + "\tinput\t\t\trst;\n" self.wires.append("rst") if invert_reset: #print "found invert reset!" wr_buf += "\twire\t\t\trst_n;\n" self.wires.append("rst_n") wr_buf = wr_buf + "\twire\t[31:0]\tin_command;\n" self.wires.append("in_command") wr_buf = wr_buf + "\twire\t[31:0]\tin_address;\n" self.wires.append("in_address") wr_buf = wr_buf + "\twire\t[31:0]\tin_data;\n" self.wires.append("in_data") wr_buf = wr_buf + "\twire\t[27:0]\tin_data_count;\n" self.wires.append("in_data_count") wr_buf = wr_buf + "\twire\t\t\tih_ready;\n\n" self.wires.append("ih_ready") wr_buf = wr_buf + "\twire\t\t\tih_reset;\n\n" self.wires.append("ih_reset") wr_buf = wr_buf + "\t//output handler signals\n" wr_buf = wr_buf + "\twire\t[31:0]\tout_status;\n" self.wires.append("out_status") wr_buf = wr_buf + "\twire\t[31:0]\tout_address;\n" self.wires.append("out_address") wr_buf = wr_buf + "\twire\t[31:0]\tout_data;\n" self.wires.append("out_data") wr_buf = wr_buf + "\twire\t[27:0]\tout_data_count;\n" self.wires.append("out_data_count") wr_buf = wr_buf + "\twire\t\t\toh_ready;\n" self.wires.append("oh_ready") wr_buf = wr_buf + "\twire\t\t\toh_en;\n\n" self.wires.append("oh_en") wr_buf = wr_buf + "\t//master signals\n" wr_buf = wr_buf + "\twire\t\t\tmaster_ready;\n" self.wires.append("master_ready") wr_buf = wr_buf + "\twire\t\t\twbm_we_o;\n" self.wires.append("wbm_we_o") wr_buf = wr_buf + "\twire\t\t\twbm_cyc_o;\n" self.wires.append("wbm_cyc_o") wr_buf = wr_buf + "\twire\t\t\twbm_stb_o;\n" self.wires.append("wbm_stb_o") wr_buf = wr_buf + "\twire\t[3:0]\twbm_sel_o;\n" self.wires.append("wbm_sel_o") wr_buf = wr_buf + "\twire\t[31:0]\twbm_adr_o;\n" self.wires.append("wbm_adr_o") wr_buf = wr_buf + "\twire\t[31:0]\twbm_dat_i;\n" self.wires.append("wbm_dat_i") wr_buf = wr_buf + "\twire\t[31:0]\twbm_dat_o;\n" self.wires.append("wbm_dat_o") wr_buf = wr_buf + "\twire\t\t\twbm_ack_i;\n" self.wires.append("wbm_ack_i") wr_buf = wr_buf + "\twire\t\t\twbm_int_i;\n\n" self.wires.append("wbm_int_i") wr_buf = wr_buf + "\twire\t\t\tmem_we_o;\n" self.wires.append("mem_we_o") wr_buf = wr_buf + "\twire\t\t\tmem_cyc_o;\n" self.wires.append("mem_cyc_o") wr_buf = wr_buf + "\twire\t\t\tmem_stb_o;\n" self.wires.append("mem_stb_o") wr_buf = wr_buf + "\twire\t[3:0]\tmem_sel_o;\n" self.wires.append("mem_sel_o") wr_buf = wr_buf + "\twire\t[31:0]\tmem_adr_o;\n" self.wires.append("mem_adr_o") wr_buf = wr_buf + "\twire\t[31:0]\tmem_dat_i;\n" self.wires.append("mem_dat_i") wr_buf = wr_buf + "\twire\t[31:0]\tmem_dat_o;\n" self.wires.append("mem_dat_o") wr_buf = wr_buf + "\twire\t\t\tmem_ack_i;\n" self.wires.append("mem_ack_i") wr_buf = wr_buf + "\twire\t\t\tmem_int_i;\n" self.wires.append("mem_int_i") wr_buf = wr_buf + "\twire\t[31:0]\twbm_debug_out;\n\n" self.wires.append("wbm_debug_out"); #put the in clock on the global buffer #wr_buf = wr_buf + "\t//add a global clock buffer to the input clock\n" #wr_buf = wr_buf + "\tIBUFG clk_ibuf(.I(clk_in), .O(clk));\n\n" wr_buf = wr_buf + "\t//slave signals\n\n" for i in range (0, num_slaves): wr_buf = wr_buf + "\t//slave " + str(i) + "\n" wr_buf = wr_buf + "\twire\t\t\ts" + str(i) + "_wbs_we_i;\n" self.wires.append("s" + str(i) + "_wbs_we_i") wr_buf = wr_buf + "\twire\t\t\ts" + str(i) + "_wbs_cyc_i;\n" self.wires.append("s" + str(i) + "_wbs_cyc_i") wr_buf = wr_buf + "\twire\t[31:0]\ts" + str(i) + "_wbs_dat_i;\n" self.wires.append("s" + str(i) + "_wbs_dat_i") wr_buf = wr_buf + "\twire\t[31:0]\ts" + str(i) + "_wbs_dat_o;\n" self.wires.append("s" + str(i) + "_wbs_dat_o") wr_buf = wr_buf + "\twire\t[31:0]\ts" + str(i) + "_wbs_adr_i;\n" self.wires.append("s" + str(i) + "_wbs_adr_i") wr_buf = wr_buf + "\twire\t\t\ts" + str(i) + "_wbs_stb_i;\n" self.wires.append("s" + str(i) + "_wbs_stb_i") wr_buf = wr_buf + "\twire\t[3:0]\ts" + str(i) + "_wbs_sel_i;\n" self.wires.append("s" + str(i) + "_wbs_sel_i") wr_buf = wr_buf + "\twire\t\t\ts" + str(i) + "_wbs_ack_o;\n" self.wires.append("s" + str(i) + "_wbs_ack_o") wr_buf = wr_buf + "\twire\t\t\ts" + str(i) + "_wbs_int_o;\n\n" self.wires.append("s" + str(i) + "_wbs_int_o") if (en_mem_bus): for i in range (0, len(tags["MEMORY"])): wr_buf = wr_buf + "\t//mem slave " + str(i) + "\n" wr_buf = wr_buf + "\twire\t\t\tsm" + str(i) + "_wbs_we_i;\n" self.wires.append("sm" + str(i) + "_wbs_we_i") wr_buf = wr_buf + "\twire\t\t\tsm" + str(i) + "_wbs_cyc_i;\n" self.wires.append("sm" + str(i) + "_wbs_cyc_i") wr_buf = wr_buf + "\twire\t[31:0]\tsm" + str(i) + "_wbs_dat_i;\n" self.wires.append("sm" + str(i) + "_wbs_dat_i") wr_buf = wr_buf + "\twire\t[31:0]\tsm" + str(i) + "_wbs_dat_o;\n" self.wires.append("sm" + str(i) + "_wbs_dat_o") wr_buf = wr_buf + "\twire\t[31:0]\tsm" + str(i) + "_wbs_adr_i;\n" self.wires.append("sm" + str(i) + "_wbs_adr_i") wr_buf = wr_buf + "\twire\t\t\tsm" + str(i) + "_wbs_stb_i;\n" self.wires.append("sm" + str(i) + "_wbs_stb_i") wr_buf = wr_buf + "\twire\t[3:0]\tsm" + str(i) + "_wbs_sel_i;\n" self.wires.append("sm" + str(i) + "_wbs_sel_i") wr_buf = wr_buf + "\twire\t\t\tsm" + str(i) + "_wbs_ack_o;\n" self.wires.append("sm" + str(i) + "_wbs_ack_o") wr_buf = wr_buf + "\twire\t\t\tsm" + str(i) + "_wbs_int_o;\n\n" self.wires.append("sm" + str(i) + "_wbs_int_o") if debug: print "wr_buf: \n" + wr_buf #generate the IO handler io_filename = tags["INTERFACE"]["filename"] absfilepath = saputils.find_rtl_file_location(io_filename) io_tags = saputils.get_module_tags(filename = absfilepath, bus = "wishbone") io_buf = self.generate_buffer(name = "io", module_tags = io_tags, io_module = True) #for the FPGA #constraints can be a dictionary with the mappings from device #to input/output/inout multidimensional values #this should just be file with text that I can pull in, it will always be #the same! #instantiate the connection interface #should this be another script that is clled within here? #can I extrapolate the required information directly from the #file? #interconnect wi_buf = "\twishbone_interconnect wi (\n" wi_buf = wi_buf + "\t\t.clk(clk),\n" if invert_reset: wi_buf = wi_buf + "\t\t.rst(rst_n),\n\n" else: wi_buf = wi_buf + "\t\t.rst(rst),\n\n" wi_buf = wi_buf + "\t\t//master\n" wi_buf = wi_buf + "\t\t.m_we_i(wbm_we_o),\n" wi_buf = wi_buf + "\t\t.m_cyc_i(wbm_cyc_o),\n" wi_buf = wi_buf + "\t\t.m_stb_i(wbm_stb_o),\n" wi_buf = wi_buf + "\t\t.m_sel_i(wbm_sel_o),\n" wi_buf = wi_buf + "\t\t.m_ack_o(wbm_ack_i),\n" wi_buf = wi_buf + "\t\t.m_dat_i(wbm_dat_o),\n" wi_buf = wi_buf + "\t\t.m_dat_o(wbm_dat_i),\n" wi_buf = wi_buf + "\t\t.m_adr_i(wbm_adr_o),\n" wi_buf = wi_buf + "\t\t.m_int_o(wbm_int_i),\n\n" for i in range (0, num_slaves): wi_buf = wi_buf + "\t\t//slave " + str(i) + "\n" wi_buf = wi_buf + "\t\t.s" + str(i) + "_we_o (s" + str(i) + "_wbs_we_i),\n" wi_buf = wi_buf + "\t\t.s" + str(i) + "_cyc_o(s" + str(i) + "_wbs_cyc_i),\n" wi_buf = wi_buf + "\t\t.s" + str(i) + "_stb_o(s" + str(i) + "_wbs_stb_i),\n" wi_buf = wi_buf + "\t\t.s" + str(i) + "_sel_o(s" + str(i) + "_wbs_sel_i),\n" wi_buf = wi_buf + "\t\t.s" + str(i) + "_ack_i(s" + str(i) + "_wbs_ack_o),\n" wi_buf = wi_buf + "\t\t.s" + str(i) + "_dat_o(s" + str(i) + "_wbs_dat_i),\n" wi_buf = wi_buf + "\t\t.s" + str(i) + "_dat_i(s" + str(i) + "_wbs_dat_o),\n" wi_buf = wi_buf + "\t\t.s" + str(i) + "_adr_o(s" + str(i) + "_wbs_adr_i),\n" wi_buf = wi_buf + "\t\t.s" + str(i) + "_int_i(s" + str(i) + "_wbs_int_o)" if (i < num_slaves - 1): wi_buf = wi_buf + ",\n" wi_buf = wi_buf + "\n\n" wi_buf = wi_buf + "\t);" if debug: print "wi_buf: \n" + wi_buf #memory interconnect if en_mem_bus: if debug: print "make the membus" wmi_buf = "\twishbone_mem_interconnect wmi (\n" wmi_buf = wmi_buf + "\t\t.clk(clk),\n" if invert_reset: wmi_buf = wmi_buf + "\t\t.rst(rst_n),\n\n" else: wmi_buf = wmi_buf + "\t\t.rst(rst),\n\n" wmi_buf = wmi_buf + "\t\t//master\n" wmi_buf = wmi_buf + "\t\t.m_we_i(mem_we_o),\n" wmi_buf = wmi_buf + "\t\t.m_cyc_i(mem_cyc_o),\n" wmi_buf = wmi_buf + "\t\t.m_stb_i(mem_stb_o),\n" wmi_buf = wmi_buf + "\t\t.m_sel_i(mem_sel_o),\n" wmi_buf = wmi_buf + "\t\t.m_ack_o(mem_ack_i),\n" wmi_buf = wmi_buf + "\t\t.m_dat_i(mem_dat_o),\n" wmi_buf = wmi_buf + "\t\t.m_dat_o(mem_dat_i),\n" wmi_buf = wmi_buf + "\t\t.m_adr_i(mem_adr_o),\n" wmi_buf = wmi_buf + "\t\t.m_int_o(mem_int_i),\n\n" num_mems = len(tags["MEMORY"]) for i in range (0, num_mems): wmi_buf = wmi_buf + "\t//mem slave " + str(i) + "\n" wmi_buf = wmi_buf + "\t\t.s" + str(i) + "_we_o(sm" + str(i) + "_wbs_we_i),\n" wmi_buf = wmi_buf + "\t\t.s" + str(i) + "_cyc_o(sm" + str(i) + "_wbs_cyc_i),\n" wmi_buf = wmi_buf + "\t\t.s" + str(i) + "_stb_o(sm" + str(i) + "_wbs_stb_i),\n" wmi_buf = wmi_buf + "\t\t.s" + str(i) + "_sel_o(sm" + str(i) + "_wbs_sel_i),\n" wmi_buf = wmi_buf + "\t\t.s" + str(i) + "_ack_i(sm" + str(i) + "_wbs_ack_o),\n" wmi_buf = wmi_buf + "\t\t.s" + str(i) + "_dat_o(sm" + str(i) + "_wbs_dat_i),\n" wmi_buf = wmi_buf + "\t\t.s" + str(i) + "_dat_i(sm" + str(i) + "_wbs_dat_o),\n" wmi_buf = wmi_buf + "\t\t.s" + str(i) + "_adr_o(sm" + str(i) + "_wbs_adr_i),\n" wmi_buf = wmi_buf + "\t\t.s" + str(i) + "_int_i(sm" + str(i) + "_wbs_int_o)" if ((num_mems > 0) and (i < num_mems - 1)): wmi_buf = wmi_buf + ",\n" wmi_buf = wmi_buf + "\n\n" wmi_buf = wmi_buf + "\t);" if debug: print "wmi_buf: \n" + wmi_buf #instantiate the io handler #instantiate the master wm_buf = wm_buf + "\twishbone_master wm (\n" wm_buf = wm_buf + "\t\t.clk(clk),\n" if invert_reset: wm_buf = wm_buf + "\t\t.rst(rst_n),\n\n" else: wm_buf = wm_buf + "\t\t.rst(rst),\n\n" wm_buf = wm_buf + "\t\t//input handler signals\n" wm_buf = wm_buf + "\t\t.in_ready(ih_ready),\n" wm_buf = wm_buf + "\t\t.ih_reset(ih_reset),\n" wm_buf = wm_buf + "\t\t.in_command(in_command),\n" wm_buf = wm_buf + "\t\t.in_address(in_address),\n" wm_buf = wm_buf + "\t\t.in_data(in_data),\n" wm_buf = wm_buf + "\t\t.in_data_count(in_data_count),\n\n" wm_buf = wm_buf + "\t\t//output handler signals\n" wm_buf = wm_buf + "\t\t.out_ready(oh_ready),\n" wm_buf = wm_buf + "\t\t.out_en(oh_en),\n" wm_buf = wm_buf + "\t\t.out_status(out_status),\n" wm_buf = wm_buf + "\t\t.out_address(out_address),\n" wm_buf = wm_buf + "\t\t.out_data(out_data),\n" wm_buf = wm_buf + "\t\t.out_data_count(out_data_count),\n" wm_buf = wm_buf + "\t\t.master_ready(master_ready),\n\n" wm_buf = wm_buf + "\t\t//interconnect signals\n" wm_buf = wm_buf + "\t\t.wb_adr_o(wbm_adr_o),\n" wm_buf = wm_buf + "\t\t.wb_dat_o(wbm_dat_o),\n" wm_buf = wm_buf + "\t\t.wb_dat_i(wbm_dat_i),\n" wm_buf = wm_buf + "\t\t.wb_stb_o(wbm_stb_o),\n" wm_buf = wm_buf + "\t\t.wb_cyc_o(wbm_cyc_o),\n" wm_buf = wm_buf + "\t\t.wb_we_o(wbm_we_o),\n" wm_buf = wm_buf + "\t\t.wb_msk_o(wbm_msk_o),\n" wm_buf = wm_buf + "\t\t.wb_sel_o(wbm_sel_o),\n" wm_buf = wm_buf + "\t\t.wb_ack_i(wbm_ack_i),\n" wm_buf = wm_buf + "\t\t.wb_int_i(wbm_int_i),\n\n" wm_buf = wm_buf + "\t\t//memory interconnect signals\n" wm_buf = wm_buf + "\t\t.mem_adr_o(mem_adr_o),\n" wm_buf = wm_buf + "\t\t.mem_dat_o(mem_dat_o),\n" wm_buf = wm_buf + "\t\t.mem_dat_i(mem_dat_i),\n" wm_buf = wm_buf + "\t\t.mem_stb_o(mem_stb_o),\n" wm_buf = wm_buf + "\t\t.mem_cyc_o(mem_cyc_o),\n" wm_buf = wm_buf + "\t\t.mem_we_o(mem_we_o),\n" wm_buf = wm_buf + "\t\t.mem_msk_o(mem_msk_o),\n" wm_buf = wm_buf + "\t\t.mem_sel_o(mem_sel_o),\n" wm_buf = wm_buf + "\t\t.mem_ack_i(mem_ack_i),\n" wm_buf = wm_buf + "\t\t.mem_int_i(mem_int_i),\n\n" wm_buf = wm_buf + "\t\t.debug_out(wbm_debug_out)\n\n"; wm_buf = wm_buf + "\t);" if debug: print "wm_buf: \n" + wm_buf #Arbitrators #Slaves slave_index = 0 slave_buffer_list = [] absfilename = saputils.find_rtl_file_location("device_rom_table.v") slave_tags = saputils.get_module_tags(filename = absfilename, bus="wishbone") slave_buf = self.generate_buffer(name="drt", index=0, module_tags = slave_tags) slave_buffer_list.append(slave_buf) for i in range (0, len(tags["SLAVES"])): slave_name = tags["SLAVES"].keys()[i] slave = tags["SLAVES"][slave_name]["filename"] if debug: print "Slave name: " + slave absfilename = saputils.find_rtl_file_location(slave) slave_tags = saputils.get_module_tags(filename = absfilename, bus="wishbone") slave_buf = self.generate_buffer(name = slave_name, index = i + 1, module_tags = slave_tags) slave_buffer_list.append(slave_buf) #Memory devices mem_buf = "" mem_buffer_list = [] if en_mem_bus: #need to make all the memory devices for the memory bus mem_index = 0 mem_buffer_list = [] for i in range (0, len(tags["MEMORY"])): mem_name = tags["MEMORY"].keys()[i] filename = tags["MEMORY"][mem_name]["filename"] if debug: print "Mem device: " + mem_name + ", mem file: " + filename absfilename = saputils.find_rtl_file_location(filename) mem_tags = saputils.get_module_tags(filename = absfilename, bus="wishbone") mem_buf = self.generate_buffer(name = mem_name, index = i, module_tags = mem_tags, mem_slave = True) mem_buffer_list.append(mem_buf) buf_bind = "" buf_bind += "\t//assigns\n" #Generate the internal bindings if (len(self.internal_bindings.keys()) > 0): buf_bind += "\t//Internal Bindings\n" for key in self.internal_bindings.keys(): buf_bind += "\tassign\t%s\t=\t%s;\n" % (key, self.internal_bindings[key]["signal"]) #Generate the external bindings if (len(self.bindings.keys()) > 0): buf_bind += "\t//Bindings to Ports\n" for key in self.bindings.keys(): if (self.bindings[key]["direction"] == "input"): buf_bind = buf_bind + "\tassign\t" + key + "\t=\t" + self.bindings[key]["port"] + ";\n" elif (self.bindings[key]["direction"] == "output"): buf_bind = buf_bind + "\tassign\t" + self.bindings[key]["port"] + "\t=\t" + key + ";\n" if invert_reset: buf_bind += "\tassign\trst_n\t\t=\t~rst;\n" top_buffer = header + "\n\n" top_buffer += port_buf + "\n\n" top_buffer += wr_buf + "\n\n" top_buffer += io_buf + "\n\n" top_buffer += wi_buf + "\n\n" top_buffer += wmi_buf + "\n\n" if (len(arb_buf) > 0): top_buffer += arb_buf + "\n\n" top_buffer += wm_buf + "\n\n" for slave_buf in slave_buffer_list: top_buffer = top_buffer + "\n\n" + slave_buf for mem_buf in mem_buffer_list: top_buffer = top_buffer + "\n\n" + mem_buf top_buffer = top_buffer + "\n\n" + buf_bind + "\n\n" + footer return top_buffer
def generate_project(self, config_file_name, debug=False): """Generate the folders and files for the project Using the project tags and template tags this function generates all the directories and files of the project. It will go through the template structure and determine what files need to be added and call either a generation script (in the case of \"top.v\") or simply copy the file over (in the case of a peripheral or memory module. Args: config_file_name: name of the JSON configuration file Return: True: Success False: Failure Raises: TypeError IOError SapError """ #reading the project config data into the the project tags #XXX: This should be changed to an exception begin raised and not a True False statement self.read_config_file(config_file_name) board_dict = saputils.get_board_config(self.project_tags["board"]) cfiles = [] pt = self.project_tags if "constraint_files" in pt.keys(): cfiles = pt["constraint_files"] #if the user didn't specify any constraint files #load the default if len(cfiles) == 0: cfiles = board_dict["default_constraint_files"] #extrapolate the bus template #XXX: Need to check all the constraint files self.project_tags["CLOCK_RATE"] = saputils.read_clock_rate(cfiles[0]) self.read_template(self.project_tags["TEMPLATE"]) #set all the tags within the filegen structure if debug: print "set all tags wihin filegen structure" self.filegen.set_tags(self.project_tags) #generate the project directories and files saputils.create_dir(self.project_tags["BASE_DIR"]) if debug: print "generated the first dir" #generate the arbitrator tags, this is important because the top #needs the arbitrator tags arb_tags = saparbitrator.generate_arbitrator_tags( self.project_tags, False) self.project_tags["ARBITRATORS"] = arb_tags #print "Parent dir: " + self.project_tags["BASE_DIR"] for key in self.template_tags["PROJECT_TEMPLATE"]["files"]: self.recursive_structure_generator( self.template_tags["PROJECT_TEMPLATE"]["files"], key, self.project_tags["BASE_DIR"]) if debug: print "generating project directories finished" if debug: print "generate the arbitrators" self.generate_arbitrators() #Generate all the slaves for slave in self.project_tags["SLAVES"]: fdict = {"location": ""} file_dest = self.project_tags["BASE_DIR"] + "/rtl/bus/slave" fn = self.project_tags["SLAVES"][slave]["filename"] try: self.filegen.process_file(filename=fn, file_dict=fdict, directory=file_dest, debug=debug) except ModuleFactoryError as err: print "ModuleFactoryError while generating a slave: %s" % str( err) #each slave if ("MEMORY" in self.project_tags): for mem in self.project_tags["MEMORY"]: fdict = {"location": ""} file_dest = self.project_tags["BASE_DIR"] + "/rtl/bus/slave" fn = self.project_tags["MEMORY"][mem]["filename"] try: self.filegen.process_file(filename=fn, file_dict=fdict, directory=file_dest) except ModuleFactoryError as err: print "ModuleFactoryError while generating a memory slave: %s" % str( err) #Copy the user specified constraint files to the constraints directory for constraint_fname in cfiles: sap_abs_base = os.getenv("SAPLIB_BASE") abs_proj_base = saputils.resolve_linux_path( self.project_tags["BASE_DIR"]) constraint_path = self.get_constraint_path(constraint_fname) if (len(constraint_path) == 0): print "Couldn't find constraint: " + constraint_fname + ", searched in current directory and " + sap_abs_base + " /hdl/" + self.project_tags[ "board"] continue shutil.copy(constraint_path, abs_proj_base + "/constraints/" + constraint_fname) #Generate the IO handler interface_filename = self.project_tags["INTERFACE"]["filename"] fdict = {"location": ""} file_dest = self.project_tags["BASE_DIR"] + "/rtl/bus/interface" result = self.filegen.process_file(filename=interface_filename, file_dict=fdict, directory=file_dest) if debug: print "copy over the dependencies..." print "verilog files: " for f in self.filegen.verilog_file_list: print f print "dependent files: " for d in self.filegen.verilog_dependency_list: fdict = {"location": ""} file_dest = self.project_tags["BASE_DIR"] + "/dependencies" result = self.filegen.process_file(filename=d, file_dict=fdict, directory=file_dest) if debug: print d return True