Skip to content

Commit

Permalink
Merge pull request google#78 from mabrains/ngspice_regression
Browse files Browse the repository at this point in the history
Ngspice Regression
  • Loading branch information
FaragElsayed2 authored Jan 22, 2023
2 parents 380743e + 194e531 commit c223ffe
Show file tree
Hide file tree
Showing 10 changed files with 256 additions and 69 deletions.
63 changes: 53 additions & 10 deletions models/ngspice/testing/regression/bjt_beta/models_regression.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,22 +38,36 @@
PASS_THRESH = 2.0


def find_bjt(filepath):
"""
Find bjt in csv files
def find_bjt(filepath: str):
"""Find bjt in csv files
Args:
filepath (str): Path to csv file.
Returns:
float: bjt value.
"""
return os.path.exists(filepath)


def call_simulator(file_name):
def call_simulator(file_name: str):
"""Call simulation commands to perform simulation.
Args:
file_name (str): Netlist file name.
Returns:
int: Return code of the simulation. 0 for success. Non-zero for failure.
"""
return os.system(f"ngspice -b -a {file_name} -o {file_name}.log > {file_name}.log")


def ext_npn_measured(dev_data_path, device, devices, dev_path):
def ext_npn_measured(dev_data_path: str, device: str, devices: list[str], dev_path: str) -> pd.DataFrame:
"""Extract measured values from excel file.
Args:
dev_data_path (str): Path to excel file.
device (str): Device name.
devices (str): List of devices.
dev_path (str): Path to device.
Returns:
pd.DataFrame: Dataframe containing measured values.
"""
# Read Data
df = pd.read_excel(dev_data_path)

Expand Down Expand Up @@ -154,7 +168,16 @@ def ext_npn_measured(dev_data_path, device, devices, dev_path):
return df


def ext_pnp_measured(dev_data_path, device, devices, dev_path):
def ext_pnp_measured(dev_data_path: str, device: str, devices: list[str], dev_path: str) -> pd.DataFrame:
"""Extract measured values from excel file.
Args:
dev_data_path (str): Path to excel file.
device (str): Device name.
devices (str): List of devices.
dev_path (str): Path to device.
Returns:
pd.DataFrame: Dataframe containing measured values.
"""
# Read Data
df = pd.read_excel(dev_data_path)

Expand Down Expand Up @@ -255,9 +278,16 @@ def ext_pnp_measured(dev_data_path, device, devices, dev_path):
return df


def run_sim(char, dirpath, device, temp):
"""Run simulation at specific information and corner"""

def run_sim(char: str, dirpath: str, device: str, temp: float) -> dict:
"""Run simulation.
Args:
char (str): ib or ic to simulate.
dirpath (str): Path to device.
device (str): Device name.
temp (float): Temperature.
Returns:
dict: Dictionary containing simulation results.
"""
info = {}
info["device"] = device
info["temp"] = temp
Expand Down Expand Up @@ -308,7 +338,16 @@ def run_sim(char, dirpath, device, temp):
return info


def run_sims(char, df, dirpath, num_workers=mp.cpu_count()):
def run_sims(char: str, df: pd.DataFrame, dirpath: str, num_workers=mp.cpu_count()) -> pd.DataFrame:
"""Run simulations.
Args:
char (str): ib or ic to simulate.
df (pd.DataFrame): DataFrame containing device information.
dirpath (str): Path to device.
num_workers (int, optional): Number of workers. Defaults to mp.cpu_count().
Returns:
pd.DataFrame: DataFrame containing simulation results.
"""

results = []
with concurrent.futures.ThreadPoolExecutor(max_workers=num_workers) as executor:
Expand Down Expand Up @@ -377,9 +416,13 @@ def main():
"""Main function applies all regression steps"""
# ======= Checking ngspice =======
ngspice_v_ = os.popen("ngspice -v").read()
version = (ngspice_v_.split("\n")[1])
if ngspice_v_ == "":
logging.error("ngspice is not found. Please make sure ngspice is installed.")
exit(1)
elif "38" not in version:
logging.error("ngspice version is not supported. Please use ngspice version 38.")
exit(1)
# pandas setup
pd.set_option("display.max_columns", None)
pd.set_option("display.max_rows", None)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -412,9 +412,13 @@ def main():
"""Main function applies all regression steps"""
# ======= Checking ngspice =======
ngspice_v_ = os.popen("ngspice -v").read()
version = (ngspice_v_.split("\n")[1])
if ngspice_v_ == "":
logging.error("ngspice is not found. Please make sure ngspice is installed.")
exit(1)
elif "38" not in version:
logging.error("ngspice version is not supported. Please use ngspice version 38.")
exit(1)
# pandas setup
pd.set_option("display.max_columns", None)
pd.set_option("display.max_rows", None)
Expand Down Expand Up @@ -566,7 +570,7 @@ def main():
handlers=[
logging.StreamHandler(),
],
format=f"%(asctime)s | %(levelname)-7s | %(message)s",
format="%(asctime)s | %(levelname)-7s | %(message)s",
datefmt="%d-%b-%Y %H:%M:%S",
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -517,9 +517,13 @@ def main():
"""Main function applies all regression v_collector_steps"""
# ======= Checking ngspice =======
ngspice_v_ = os.popen("ngspice -v").read()
version = (ngspice_v_.split("\n")[1])
if ngspice_v_ == "":
logging.error("ngspice is not found. Please make sure ngspice is installed.")
exit(1)
elif "38" not in version:
logging.error("ngspice version is not supported. Please use ngspice version 38.")
exit(1)
# pandas setup
pd.set_option("display.max_columns", None)
pd.set_option("display.max_rows", None)
Expand Down Expand Up @@ -663,7 +667,7 @@ def main():
handlers=[
logging.StreamHandler(),
],
format=f"%(asctime)s | %(levelname)-7s | %(message)s",
format="%(asctime)s | %(levelname)-7s | %(message)s",
datefmt="%d-%b-%Y %H:%M:%S",
)

Expand Down
71 changes: 60 additions & 11 deletions models/ngspice/testing/regression/diode/models_regression.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,22 +41,36 @@
MAX_VOLTAGE = 3.3


def find_diode(filepath):
"""
Find diode in csv files
def find_diode(filepath: str) -> bool:
"""Find diode in csv files
Args:
filepath (str): Path to csv file.
Returns:
bool: True if diode is found, False otherwise.
"""
return os.path.exists(filepath)


def call_simulator(file_name):
def call_simulator(file_name: str) -> int:
"""Call simulation commands to perform simulation.
Args:
file_name (str): Netlist file name.
Returns:
int: Return code of the simulation. 0 if successful. Non-zero otherwise.
"""
return os.system(f"ngspice -b -a {file_name} -o {file_name}.log > {file_name}.log")


def ext_cv_measured(dev_data_path, device, corners, dev_path):
def ext_cv_measured(dev_data_path: str, device: str, corners: str, dev_path: str) -> pd.DataFrame:
"""Extract measured data from csv file.
Args:
dev_data_path (str): Path to csv file.
device (str): Device name.
corners (str): Corner name.
dev_path (str): Path to device directory.
Returns:
pd.DataFrame: DataFrame containing measured data.
"""
# Read Data
df = pd.read_excel(dev_data_path)

Expand Down Expand Up @@ -152,7 +166,17 @@ def ext_cv_measured(dev_data_path, device, corners, dev_path):
return df


def ext_iv_measured(dev_data_path, device, corners, dev_path):
def ext_iv_measured(dev_data_path: str, device: str, corners: str, dev_path: str) -> pd.DataFrame:
"""Extract measured data from csv file.
Args:
dev_data_path (str): Path to csv file.
device (str): Device name.
corners (str): Corner name.
dev_path (str): Path to device directory.
Returns:
pd.DataFrame: DataFrame containing measured data.
"""

# Read Data
df = pd.read_excel(dev_data_path)

Expand Down Expand Up @@ -235,8 +259,19 @@ def ext_iv_measured(dev_data_path, device, corners, dev_path):
return df


def run_sim(char, dirpath, device, length, width, corner, temp):
"""Run simulation at specific information and corner"""
def run_sim(char: str, dirpath: str, device: str, length: float, width: float, corner: str, temp: float) -> dict:
"""Run simulation.
Args:
char (str): Characteristic.
dirpath (str): Path to directory.
device (str): Device name.
length (float): Device length.
width (float): Device width.
corner (str): Corner name.
temp (float): Temperature.
Returns:
dict: Dictionary containing simulation results.
"""
netlist_tmp = f"./device_netlists/{char}.spice"

info = {}
Expand Down Expand Up @@ -286,8 +321,16 @@ def run_sim(char, dirpath, device, length, width, corner, temp):
return info


def run_sims(char, df, dirpath, num_workers=mp.cpu_count()):

def run_sims(char: str, df: pd.DataFrame, dirpath: str, num_workers=mp.cpu_count()) -> pd.DataFrame:
"""Run simulations.
Args:
char (str): Characteristic.
df (pd.DataFrame): DataFrame containing simulation parameters.
dirpath (str): Path to directory.
num_workers (int, optional): Number of workers. Defaults to mp.cpu_count().
Returns:
pd.DataFrame: DataFrame containing simulation results.
"""
results = []
with concurrent.futures.ThreadPoolExecutor(max_workers=num_workers) as executor:
futures_list = []
Expand Down Expand Up @@ -334,11 +377,17 @@ def run_sims(char, df, dirpath, num_workers=mp.cpu_count()):


def main():
"""Main function.
"""
# ======= Checking ngspice =======
ngspice_v_ = os.popen("ngspice -v").read()
version = (ngspice_v_.split("\n")[1])
if ngspice_v_ == "":
logging.error("ngspice is not found. Please make sure ngspice is installed.")
exit(1)
elif "38" not in version:
logging.error("ngspice version is not supported. Please use ngspice version 38.")
exit(1)
# pandas setup
pd.set_option("display.max_columns", None)
pd.set_option("display.max_rows", None)
Expand Down Expand Up @@ -553,7 +602,7 @@ def main():
handlers=[
logging.StreamHandler(),
],
format=f"%(asctime)s | %(levelname)-7s | %(message)s",
format="%(asctime)s | %(levelname)-7s | %(message)s",
datefmt="%d-%b-%Y %H:%M:%S",
)

Expand Down
14 changes: 9 additions & 5 deletions models/ngspice/testing/regression/mimcap_c/models_regression.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,10 @@ def run_sim(dirpath, device, length, width, corner, temp=25):
try:
mim = find_mimcap(f"{netlist_path}.log")

except Exception as e:
except Exception:
mim = 0.0

except Exception as e:
except Exception:
mim = 0.0

info["mim_sim_unscaled"] = mim
Expand Down Expand Up @@ -188,9 +188,13 @@ def run_sims(df, dirpath, num_workers=mp.cpu_count()):
def main():
# ======= Checking ngspice =======
ngspice_v_ = os.popen("ngspice -v").read()
version = (ngspice_v_.split("\n")[1])
if ngspice_v_ == "":
logging.error("ngspice is not found. Please make sure ngspice is installed.")
exit(1)
elif "38" not in version:
logging.error("ngspice version is not supported. Please use ngspice version 38.")
exit(1)
# pandas setup
pd.set_option("display.max_columns", None)
pd.set_option("display.max_rows", None)
Expand Down Expand Up @@ -228,7 +232,7 @@ def main():
logging.info("######" * 10)
logging.info(f"# Checking Device {dev}")

mim_data_files = glob.glob(f"../../180MCU_SPICE_DATA/Cap/mimcap_fc.nl_out.xlsx")
mim_data_files = glob.glob("../../180MCU_SPICE_DATA/Cap/mimcap_fc.nl_out.xlsx")
if len(mim_data_files) < 1:
logging.info(f"# Can't find mimcap file for device: {dev}")
mim_file = ""
Expand Down Expand Up @@ -284,15 +288,15 @@ def main():
arguments = docopt(__doc__, version="comparator: 0.1")
workers_count = (
os.cpu_count() * 2
if arguments["--num_cores"] == None
if arguments["--num_cores"] is None
else int(arguments["--num_cores"])
)
logging.basicConfig(
level=logging.DEBUG,
handlers=[
logging.StreamHandler(),
],
format=f"%(asctime)s | %(levelname)-7s | %(message)s",
format="%(asctime)s | %(levelname)-7s | %(message)s",
datefmt="%d-%b-%Y %H:%M:%S",
)

Expand Down
Loading

0 comments on commit c223ffe

Please sign in to comment.