From 5349323acdda050cf1b020022b0404ead7d56788 Mon Sep 17 00:00:00 2001 From: mrg Date: Thu, 2 Apr 2020 09:47:39 -0700 Subject: [PATCH] PEP8 cleanup. DRC/LVS returns errors. --- compiler/base/hierarchy_design.py | 111 +++++++++++++---------- compiler/modules/hierarchical_decoder.py | 18 ++-- compiler/sram/sram_base.py | 2 +- 3 files changed, 75 insertions(+), 56 deletions(-) diff --git a/compiler/base/hierarchy_design.py b/compiler/base/hierarchy_design.py index 09d7ea9c..5119da2e 100644 --- a/compiler/base/hierarchy_design.py +++ b/compiler/base/hierarchy_design.py @@ -29,39 +29,42 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout): hierarchy_layout.layout.__init__(self, name) self.init_graph_params() - def get_layout_pins(self,inst): + def get_layout_pins(self, inst): """ Return a map of pin locations of the instance offset """ # find the instance for i in self.insts: if i.name == inst.name: break else: - debug.error("Couldn't find instance {0}".format(inst_name),-1) + debug.error("Couldn't find instance {0}".format(inst_name), -1) inst_map = inst.mod.pin_map return inst_map - - def DRC_LVS(self, final_verification=False, top_level=False): + def DRC_LVS(self, final_verification=False, force_check=False): """Checks both DRC and LVS for a module""" # Final verification option does not allow nets to be connected by label. # Unit tests will check themselves. - if OPTS.is_unit_test: + if not force_check and OPTS.is_unit_test: return ("skipped", "skipped") - if not OPTS.check_lvsdrc: + if not force_check and not OPTS.check_lvsdrc: return ("skipped", "skipped") # Do not run if disabled in options. - if (OPTS.inline_lvsdrc or top_level): + if (OPTS.inline_lvsdrc or force_check): - tempspice = "{0}/{1}.sp".format(OPTS.openram_temp,self.name) - tempgds = "{0}/{1}.gds".format(OPTS.openram_temp,self.name) + tempspice = "{0}/{1}.sp".format(OPTS.openram_temp, self.name) + tempgds = "{0}/{1}.gds".format(OPTS.openram_temp, self.name) self.sp_write(tempspice) self.gds_write(tempgds) - num_drc_errors = verify.run_drc(self.name, tempgds, extract=True, final_verification=final_verification) - num_lvs_errors = verify.run_lvs(self.name, tempgds, tempspice, final_verification=final_verification) - debug.check(num_drc_errors == 0,"DRC failed for {0} with {1} error(s)".format(self.name,num_drc_errors)) - debug.check(num_lvs_errors == 0,"LVS failed for {0} with {1} errors(s)".format(self.name,num_lvs_errors)) + num_drc_errors = verify.run_drc(self.name, tempgds, extract=True, final_verification=final_verification) + num_lvs_errors = verify.run_lvs(self.name, tempgds, tempspice, final_verification=final_verification) + debug.check(num_drc_errors == 0, + "DRC failed for {0} with {1} error(s)".format(self.name, + num_drc_errors)) + debug.check(num_lvs_errors == 0, + "LVS failed for {0} with {1} errors(s)".format(self.name, + num_lvs_errors)) os.remove(tempspice) os.remove(tempgds) @@ -74,10 +77,12 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout): # Do not run if disabled in options. if (not OPTS.is_unit_test and OPTS.check_lvsdrc and (OPTS.inline_lvsdrc or final_verification)): - tempgds = "{0}/{1}.gds".format(OPTS.openram_temp,self.name) + tempgds = "{0}/{1}.gds".format(OPTS.openram_temp, self.name) self.gds_write(tempgds) - num_errors = verify.run_drc(self.name, tempgds, final_verification=final_verification) - debug.check(num_errors == 0,"DRC failed for {0} with {1} error(s)".format(self.name,num_error)) + num_errors = verify.run_drc(self.name, tempgds, final_verification=final_verification) + debug.check(num_errors == 0, + "DRC failed for {0} with {1} error(s)".format(self.name, + num_errors)) os.remove(tempgds) @@ -91,12 +96,14 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout): # Do not run if disabled in options. if (not OPTS.is_unit_test and OPTS.check_lvsdrc and (OPTS.inline_lvsdrc or final_verification)): - tempspice = "{0}/{1}.sp".format(OPTS.openram_temp,self.name) - tempgds = "{0}/{1}.gds".format(OPTS.openram_temp,self.name) + tempspice = "{0}/{1}.sp".format(OPTS.openram_temp, self.name) + tempgds = "{0}/{1}.gds".format(OPTS.openram_temp, self.name) self.sp_write(tempspice) self.gds_write(tempgds) num_errors = verify.run_lvs(self.name, tempgds, tempspice, final_verification=final_verification) - debug.check(num_errors == 0,"LVS failed for {0} with {1} error(s)".format(self.name,num_errors)) + debug.check(num_errors == 0, + "LVS failed for {0} with {1} error(s)".format(self.name, + num_errors)) os.remove(tempspice) os.remove(tempgds) @@ -106,40 +113,44 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout): def init_graph_params(self): """Initializes parameters relevant to the graph creation""" - #Only initializes a set for checking instances which should not be added + # Only initializes a set for checking instances which should not be added self.graph_inst_exclude = set() - def build_graph(self, graph, inst_name, port_nets): + def build_graph(self, graph, inst_name, port_nets): """Recursively create graph from instances in module.""" - #Translate port names to external nets + # Translate port names to external nets if len(port_nets) != len(self.pins): - debug.error("Port length mismatch:\nExt nets={}, Ports={}".format(port_nets,self.pins),1) - port_dict = {pin:port for pin,port in zip(self.pins, port_nets)} + debug.error("Port length mismatch:\nExt nets={}, Ports={}".format(port_nets, + self.pins), + 1) + port_dict = {pin: port for pin, port in zip(self.pins, port_nets)} debug.info(3, "Instance name={}".format(inst_name)) for subinst, conns in zip(self.insts, self.conns): if subinst in self.graph_inst_exclude: continue - subinst_name = inst_name+'.X'+subinst.name + subinst_name = inst_name + '.X' + subinst.name subinst_ports = self.translate_nets(conns, port_dict, inst_name) subinst.mod.build_graph(graph, subinst_name, subinst_ports) def build_names(self, name_dict, inst_name, port_nets): """Collects all the nets and the parent inst of that net.""" - #Translate port names to external nets + # Translate port names to external nets if len(port_nets) != len(self.pins): - debug.error("Port length mismatch:\nExt nets={}, Ports={}".format(port_nets,self.pins),1) - port_dict = {pin:port for pin,port in zip(self.pins, port_nets)} + debug.error("Port length mismatch:\nExt nets={}, Ports={}".format(port_nets, + self.pins), + 1) + port_dict = {pin: port for pin, port in zip(self.pins, port_nets)} debug.info(3, "Instance name={}".format(inst_name)) for subinst, conns in zip(self.insts, self.conns): - subinst_name = inst_name+'.X'+subinst.name + subinst_name = inst_name + '.X' + subinst.name subinst_ports = self.translate_nets(conns, port_dict, inst_name) for si_port, conn in zip(subinst_ports, conns): - #Only add for first occurrence + # Only add for first occurrence if si_port.lower() not in name_dict: - mod_info = {'mod':self, 'int_net':conn} + mod_info = {'mod': self, 'int_net': conn} name_dict[si_port.lower()] = mod_info - subinst.mod.build_names(name_dict, subinst_name, subinst_ports) + subinst.mod.build_names(name_dict, subinst_name, subinst_ports) def find_aliases(self, inst_name, port_nets, path_nets, alias, alias_mod, exclusion_set=None): """Given a list of nets, will compare the internal alias of a mod to determine @@ -159,17 +170,17 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout): int_mod = self.name_dict[net]['mod'] if int_mod.is_net_alias(int_net, alias, alias_mod, exclusion_set): aliases.append(net) - return aliases + return aliases def is_net_alias(self, known_net, net_alias, mod, exclusion_set): """Checks if the alias_net in input mod is the same as the input net for this mod (self).""" if self in exclusion_set: return False - #Check ports of this mod + # Check ports of this mod for pin in self.pins: if self.is_net_alias_name_check(known_net, pin, net_alias, mod): return True - #Check connections of all other subinsts + # Check connections of all other subinsts mod_set = set() for subinst, inst_conns in zip(self.insts, self.conns): for inst_conn, mod_pin in zip(inst_conns, subinst.mod.pins): @@ -179,7 +190,7 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout): if subinst.mod.is_net_alias(mod_pin, net_alias, mod, exclusion_set): return True mod_set.add(subinst.mod) - return False + return False def is_net_alias_name_check(self, parent_net, child_net, alias_net, mod): """Utility function for checking single net alias.""" @@ -188,8 +199,10 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout): parent_net.lower() == alias_net.lower() def get_mod_net(self, parent_net, child_inst, child_conns): - """Given an instance and net, returns the internal net in the mod - corresponding to input net.""" + """ + Given an instance and net, returns the internal net in the mod + corresponding to input net. + """ for conn, pin in zip(child_conns, child_inst.mod.pins): if parent_net.lower() == conn.lower(): return pin @@ -203,27 +216,27 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout): converted_conns.append(port_dict[conn]) else: converted_conns.append("{}.{}".format(inst_name, conn)) - return converted_conns + return converted_conns def add_graph_edges(self, graph, port_nets): """For every input, adds an edge to every output. Only intended to be used for gates and other simple modules.""" - #The final pin names will depend on the spice hierarchy, so - #they are passed as an input. - pin_dict = {pin:port for pin,port in zip(self.pins, port_nets)} + # The final pin names will depend on the spice hierarchy, so + # they are passed as an input. + pin_dict = {pin: port for pin, port in zip(self.pins, port_nets)} input_pins = self.get_inputs() output_pins = self.get_outputs() inout_pins = self.get_inouts() - for inp in input_pins+inout_pins: - for out in output_pins+inout_pins: - if inp != out: #do not add self loops - graph.add_edge(pin_dict[inp], pin_dict[out], self) + for inp in input_pins + inout_pins: + for out in output_pins + inout_pins: + if inp != out: # do not add self loops + graph.add_edge(pin_dict[inp], pin_dict[out], self) def __str__(self): """ override print function output """ pins = ",".join(self.pins) insts = [" {}".format(x) for x in self.insts] - objs = [" {}".format(x) for x in self.objs] + objs = [" {}".format(x) for x in self.objs] s = "********** design {0} **********".format(self.name) s += "\n pins ({0})={1}\n".format(len(self.pins), pins) s += "\n objs ({0})=\n{1}\n".format(len(self.objs), "\n".join(objs)) @@ -234,8 +247,8 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout): """ override print function output """ text="( design: " + self.name + " pins=" + str(self.pins) + " " + str(self.width) + "x" + str(self.height) + " )\n" for i in self.objs: - text+=str(i)+",\n" + text+=str(i) + ",\n" for i in self.insts: - text+=str(i)+",\n" + text+=str(i) + ",\n" return text diff --git a/compiler/modules/hierarchical_decoder.py b/compiler/modules/hierarchical_decoder.py index ebc67ee6..fbc3e535 100644 --- a/compiler/modules/hierarchical_decoder.py +++ b/compiler/modules/hierarchical_decoder.py @@ -37,13 +37,19 @@ class hierarchical_decoder(design.design): def find_decoder_height(self): b = factory.create(module_type="bitcell") - cell_height = b.height - and3 = factory.create(module_type="pand3", - height=cell_height) - - # Try to make a nand with a given height - # Default return (b.height, 1) + + cell_multiple = 1 + while cell_multiple < 3: + cell_height = cell_multiple * b.height + and3 = factory.create(module_type="pand3", + height=cell_height) + (drc_errors, lvs_errors) = and3.DRC_LVS(force_check=True) + if drc_errors + lvs_errors == 0: + return (cell_height, cell_multiple) + cell_multiple += 1 + else: + debug.error("Couldn't find a valid decoder height multiple.", -1) def create_netlist(self): self.add_modules() diff --git a/compiler/sram/sram_base.py b/compiler/sram/sram_base.py index e8a91486..38f89bc6 100644 --- a/compiler/sram/sram_base.py +++ b/compiler/sram/sram_base.py @@ -121,7 +121,7 @@ class sram_base(design, verilog, lef): start_time = datetime.datetime.now() # We only enable final verification if we have routed the design - self.DRC_LVS(final_verification=OPTS.route_supplies, top_level=True) + self.DRC_LVS(final_verification=OPTS.route_supplies, roce_check=True) if not OPTS.is_unit_test: print_time("Verification", datetime.datetime.now(), start_time)