2019-04-26 21:21:50 +02:00
|
|
|
# See LICENSE for licensing information.
|
|
|
|
|
#
|
2023-01-29 07:56:27 +01:00
|
|
|
# Copyright (c) 2016-2023 Regents of the University of California and The Board
|
2019-06-14 17:43:41 +02:00
|
|
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
|
|
|
|
# (acting for and on behalf of Oklahoma State University)
|
|
|
|
|
# All rights reserved.
|
2019-04-26 21:21:50 +02:00
|
|
|
#
|
2022-11-27 22:01:20 +01:00
|
|
|
from openram import debug
|
|
|
|
|
from openram.tech import parameter
|
|
|
|
|
|
2018-11-08 09:10:51 +01:00
|
|
|
|
|
|
|
|
class logical_effort():
|
|
|
|
|
"""
|
|
|
|
|
Class to support the values behind logical effort. Useful for storing the different components
|
|
|
|
|
such as logical effort, electrical effort, and parasitic delay.
|
|
|
|
|
"""
|
|
|
|
|
beta = parameter["beta"]
|
|
|
|
|
min_inv_cin = 1+beta
|
2018-11-10 02:14:52 +01:00
|
|
|
pinv=parameter["min_inv_para_delay"]
|
2019-04-02 10:09:31 +02:00
|
|
|
tau = parameter['le_tau']
|
2020-11-03 15:29:17 +01:00
|
|
|
|
2018-12-18 08:32:02 +01:00
|
|
|
def __init__(self, name, size, cin, cout, parasitic, out_is_rise=True):
|
|
|
|
|
self.name = name
|
2018-11-08 09:10:51 +01:00
|
|
|
self.cin = cin
|
|
|
|
|
self.cout = cout
|
|
|
|
|
self.logical_effort = (self.cin/size)/logical_effort.min_inv_cin
|
2019-08-08 10:57:04 +02:00
|
|
|
self.electrical_effort = self.cout/self.cin
|
2018-11-09 05:47:34 +01:00
|
|
|
self.parasitic_scale = parasitic
|
2018-11-15 08:34:53 +01:00
|
|
|
self.is_rise = out_is_rise
|
2020-11-03 15:29:17 +01:00
|
|
|
|
2018-11-09 05:47:34 +01:00
|
|
|
def __str__(self):
|
2018-12-18 08:32:02 +01:00
|
|
|
return "Name={}, g={}, h={}, p={}*pinv, rise_delay={}".format(self.name,
|
|
|
|
|
self.logical_effort,
|
2019-08-08 10:57:04 +02:00
|
|
|
self.electrical_effort,
|
2018-12-18 08:32:02 +01:00
|
|
|
self.parasitic_scale,
|
|
|
|
|
self.is_rise
|
2020-11-03 15:29:17 +01:00
|
|
|
)
|
2018-12-18 08:32:02 +01:00
|
|
|
|
2018-11-09 05:47:34 +01:00
|
|
|
def get_stage_effort(self):
|
2019-08-08 10:57:04 +02:00
|
|
|
return self.logical_effort*self.electrical_effort
|
2020-11-03 15:29:17 +01:00
|
|
|
|
2019-04-02 10:09:31 +02:00
|
|
|
def get_parasitic_delay(self):
|
2019-08-08 10:57:04 +02:00
|
|
|
return logical_effort.pinv*self.parasitic_scale
|
2020-11-03 15:29:17 +01:00
|
|
|
|
2019-04-02 10:09:31 +02:00
|
|
|
def get_stage_delay(self):
|
|
|
|
|
return self.get_stage_effort()+self.get_parasitic_delay()
|
2019-01-03 14:51:28 +01:00
|
|
|
|
2019-04-02 10:09:31 +02:00
|
|
|
def get_absolute_delay(self):
|
|
|
|
|
return logical_effort.tau*self.get_stage_delay()
|
2020-11-03 15:29:17 +01:00
|
|
|
|
2019-04-02 10:09:31 +02:00
|
|
|
def calculate_delays(stage_effort_list):
|
2019-01-03 14:51:28 +01:00
|
|
|
"""Convert stage effort objects to list of delay values"""
|
2019-04-02 10:09:31 +02:00
|
|
|
return [stage.get_stage_delay() for stage in stage_effort_list]
|
2020-11-03 15:29:17 +01:00
|
|
|
|
2019-04-02 10:09:31 +02:00
|
|
|
def calculate_relative_delay(stage_effort_list):
|
2018-11-09 05:47:34 +01:00
|
|
|
"""Calculates the total delay of a given delay path made of a list of logical effort objects."""
|
2019-04-02 10:09:31 +02:00
|
|
|
total_rise_delay, total_fall_delay = calculate_relative_rise_fall_delays(stage_effort_list)
|
2018-11-15 08:34:53 +01:00
|
|
|
return total_rise_delay + total_fall_delay
|
2019-04-02 10:09:31 +02:00
|
|
|
|
|
|
|
|
def calculate_absolute_delay(stage_effort_list):
|
|
|
|
|
"""Calculates the total delay of a given delay path made of a list of logical effort objects."""
|
|
|
|
|
total_delay = 0
|
|
|
|
|
for stage in stage_effort_list:
|
|
|
|
|
total_delay+=stage.get_absolute_delay()
|
|
|
|
|
return total_delay
|
2020-11-03 15:29:17 +01:00
|
|
|
|
2019-04-02 10:09:31 +02:00
|
|
|
def calculate_relative_rise_fall_delays(stage_effort_list):
|
2018-11-15 08:34:53 +01:00
|
|
|
"""Calculates the rise/fall delays of a given delay path made of a list of logical effort objects."""
|
2018-12-06 02:10:11 +01:00
|
|
|
debug.info(2, "Calculating rise/fall relative delays")
|
2018-11-15 08:34:53 +01:00
|
|
|
total_rise_delay, total_fall_delay = 0,0
|
2018-11-09 05:47:34 +01:00
|
|
|
for stage in stage_effort_list:
|
2018-12-18 08:32:02 +01:00
|
|
|
debug.info(2, stage)
|
2018-11-15 08:34:53 +01:00
|
|
|
if stage.is_rise:
|
2019-04-02 10:09:31 +02:00
|
|
|
total_rise_delay += stage.get_stage_delay()
|
2018-11-15 08:34:53 +01:00
|
|
|
else:
|
2019-04-02 10:09:31 +02:00
|
|
|
total_fall_delay += stage.get_stage_delay()
|
2018-11-15 08:34:53 +01:00
|
|
|
return total_rise_delay, total_fall_delay
|
2020-11-03 15:29:17 +01:00
|
|
|
|
2019-04-04 01:19:49 +02:00
|
|
|
def convert_farad_to_relative_c(c_farad):
|
|
|
|
|
"""Converts capacitance in Femto-Farads to relative capacitance."""
|
|
|
|
|
return c_farad*parameter['cap_relative_per_ff']
|
2020-11-03 15:29:17 +01:00
|
|
|
|
2019-08-08 10:57:04 +02:00
|
|
|
def convert_relative_c_to_farad(c_relative):
|
|
|
|
|
"""Converts capacitance in logical effort relative units to Femto-Farads."""
|
2022-07-13 19:57:56 +02:00
|
|
|
return c_relative/parameter['cap_relative_per_ff']
|