2016-11-08 18:57:35 +01:00
|
|
|
import hierarchy_layout
|
|
|
|
|
import hierarchy_spice
|
|
|
|
|
import globals
|
2017-11-14 23:59:14 +01:00
|
|
|
import verify
|
2017-06-02 20:11:57 +02:00
|
|
|
import debug
|
2016-11-08 18:57:35 +01:00
|
|
|
import os
|
2017-11-16 22:52:58 +01:00
|
|
|
from globals import OPTS
|
2016-11-08 18:57:35 +01:00
|
|
|
|
2018-11-01 22:02:33 +01:00
|
|
|
total_drc_errors = 0
|
|
|
|
|
total_lvs_errors = 0
|
2017-06-02 20:11:57 +02:00
|
|
|
|
2018-07-10 00:42:46 +02:00
|
|
|
class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout):
|
2016-11-08 18:57:35 +01:00
|
|
|
"""
|
|
|
|
|
Design Class for all modules to inherit the base features.
|
|
|
|
|
Class consisting of a set of modules and instances of these modules
|
|
|
|
|
"""
|
2017-06-02 20:11:57 +02:00
|
|
|
name_map = []
|
2016-11-08 18:57:35 +01:00
|
|
|
|
|
|
|
|
def __init__(self, name):
|
2019-01-17 01:15:38 +01:00
|
|
|
self.gds_file = OPTS.openram_tech + "gds_lib/" + name + ".gds"
|
|
|
|
|
self.sp_file = OPTS.openram_tech + "sp_lib/" + name + ".sp"
|
2016-11-08 18:57:35 +01:00
|
|
|
|
|
|
|
|
self.name = name
|
|
|
|
|
hierarchy_layout.layout.__init__(self, name)
|
|
|
|
|
hierarchy_spice.spice.__init__(self, name)
|
2017-06-02 20:11:57 +02:00
|
|
|
|
2019-01-17 01:15:38 +01:00
|
|
|
|
2017-08-07 19:24:45 +02:00
|
|
|
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)
|
|
|
|
|
inst_map = inst.mod.pin_map
|
|
|
|
|
return inst_map
|
2017-06-02 20:11:57 +02:00
|
|
|
|
2016-11-08 18:57:35 +01:00
|
|
|
|
2019-04-01 19:35:17 +02:00
|
|
|
def DRC_LVS(self, final_verification=False, top_level=False):
|
2016-11-08 18:57:35 +01:00
|
|
|
"""Checks both DRC and LVS for a module"""
|
2019-04-01 19:35:17 +02:00
|
|
|
|
|
|
|
|
# Final verification option does not allow nets to be connected by label.
|
2018-07-11 01:39:32 +02:00
|
|
|
# Unit tests will check themselves.
|
2019-04-01 19:35:17 +02:00
|
|
|
if OPTS.is_unit_test:
|
|
|
|
|
return
|
|
|
|
|
if not OPTS.check_lvsdrc:
|
|
|
|
|
return
|
2018-07-11 01:39:32 +02:00
|
|
|
# Do not run if disabled in options.
|
2019-04-01 19:35:17 +02:00
|
|
|
if (OPTS.inline_lvsdrc or top_level):
|
2018-11-15 19:45:33 +01:00
|
|
|
|
2018-11-01 22:02:33 +01:00
|
|
|
global total_drc_errors
|
|
|
|
|
global total_lvs_errors
|
2019-02-21 20:16:21 +01:00
|
|
|
tempspice = "{0}/{1}.sp".format(OPTS.openram_temp,self.name)
|
|
|
|
|
tempgds = "{0}/{1}.gds".format(OPTS.openram_temp,self.name)
|
2016-11-08 18:57:35 +01:00
|
|
|
self.sp_write(tempspice)
|
|
|
|
|
self.gds_write(tempgds)
|
2018-11-15 19:45:33 +01:00
|
|
|
|
|
|
|
|
num_drc_errors = verify.run_drc(self.name, tempgds, final_verification)
|
|
|
|
|
num_lvs_errors = verify.run_lvs(self.name, tempgds, tempspice, final_verification)
|
2018-11-01 22:02:33 +01:00
|
|
|
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))
|
|
|
|
|
total_drc_errors += num_drc_errors
|
|
|
|
|
total_lvs_errors += num_lvs_errors
|
2018-11-15 19:45:33 +01:00
|
|
|
|
2016-11-08 18:57:35 +01:00
|
|
|
os.remove(tempspice)
|
|
|
|
|
os.remove(tempgds)
|
|
|
|
|
|
2018-11-14 01:51:19 +01:00
|
|
|
def DRC(self, final_verification=False):
|
2016-11-08 18:57:35 +01:00
|
|
|
"""Checks DRC for a module"""
|
2018-07-11 01:39:32 +02:00
|
|
|
# Unit tests will check themselves.
|
|
|
|
|
# Do not run if disabled in options.
|
2018-11-15 19:45:33 +01:00
|
|
|
|
2018-11-14 02:41:32 +01:00
|
|
|
if (not OPTS.is_unit_test and OPTS.check_lvsdrc and (OPTS.inline_lvsdrc or final_verification)):
|
2018-11-01 22:02:33 +01:00
|
|
|
global total_drc_errors
|
2019-02-24 16:26:21 +01:00
|
|
|
tempgds = "{0}/{1}.gds".format(OPTS.openram_temp,self.name)
|
2016-11-08 18:57:35 +01:00
|
|
|
self.gds_write(tempgds)
|
2018-11-15 19:45:33 +01:00
|
|
|
num_errors = verify.run_drc(self.name, tempgds, final_verification)
|
2018-11-01 22:02:33 +01:00
|
|
|
total_drc_errors += num_errors
|
|
|
|
|
debug.check(num_errors == 0,"DRC failed for {0} with {1} error(s)".format(self.name,num_error))
|
2018-11-15 19:45:33 +01:00
|
|
|
|
2016-11-08 18:57:35 +01:00
|
|
|
os.remove(tempgds)
|
|
|
|
|
|
2018-02-05 23:52:51 +01:00
|
|
|
def LVS(self, final_verification=False):
|
2016-11-08 18:57:35 +01:00
|
|
|
"""Checks LVS for a module"""
|
2018-07-11 01:39:32 +02:00
|
|
|
# Unit tests will check themselves.
|
|
|
|
|
# Do not run if disabled in options.
|
2018-11-15 19:45:33 +01:00
|
|
|
|
2018-11-14 02:41:32 +01:00
|
|
|
if (not OPTS.is_unit_test and OPTS.check_lvsdrc and (OPTS.inline_lvsdrc or final_verification)):
|
2018-11-01 22:02:33 +01:00
|
|
|
global total_lvs_errors
|
2019-02-24 16:26:21 +01:00
|
|
|
tempspice = "{0}/{1}.sp".format(OPTS.openram_temp,self.name)
|
|
|
|
|
tempgds = "{0}/{1}.gds".format(OPTS.openram_temp,self.name)
|
2016-11-08 18:57:35 +01:00
|
|
|
self.sp_write(tempspice)
|
|
|
|
|
self.gds_write(tempgds)
|
2018-11-01 22:02:33 +01:00
|
|
|
num_errors = verify.run_lvs(self.name, tempgds, tempspice, final_verification)
|
|
|
|
|
total_lvs_errors += num_errors
|
|
|
|
|
debug.check(num_errors == 0,"LVS failed for {0} with {1} error(s)".format(self.name,num_errors))
|
2016-11-08 18:57:35 +01:00
|
|
|
os.remove(tempspice)
|
|
|
|
|
os.remove(tempgds)
|
|
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
|
""" override print function output """
|
|
|
|
|
return "design: " + self.name
|
|
|
|
|
|
|
|
|
|
def __repr__(self):
|
|
|
|
|
""" 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"
|
|
|
|
|
for i in self.insts:
|
|
|
|
|
text+=str(i)+",\n"
|
|
|
|
|
return text
|
2018-02-21 03:22:23 +01:00
|
|
|
|