mirror of https://github.com/VLSIDA/OpenRAM.git
Removed windows EOL characters.
This commit is contained in:
parent
b44f840814
commit
134bf573ec
|
|
@ -1,120 +1,124 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
|
|
||||||
from .simulation import simulation
|
from .simulation import simulation
|
||||||
from globals import OPTS
|
from globals import OPTS
|
||||||
import debug
|
import debug
|
||||||
import tech
|
import tech
|
||||||
|
|
||||||
import math
|
import math
|
||||||
|
|
||||||
class cacti(simulation):
|
class cacti(simulation):
|
||||||
"""
|
"""
|
||||||
Delay model for the SRAM which which
|
Delay model for the SRAM which which
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, sram, spfile, corner):
|
def __init__(self, sram, spfile, corner):
|
||||||
super().__init__(sram, spfile, corner)
|
super().__init__(sram, spfile, corner)
|
||||||
|
|
||||||
# self.targ_read_ports = []
|
# self.targ_read_ports = []
|
||||||
# self.targ_write_ports = []
|
# self.targ_write_ports = []
|
||||||
# self.period = 0
|
# self.period = 0
|
||||||
# if self.write_size:
|
# if self.write_size:
|
||||||
# self.num_wmasks = int(math.ceil(self.word_size / self.write_size))
|
# self.num_wmasks = int(math.ceil(self.word_size / self.write_size))
|
||||||
# else:
|
# else:
|
||||||
# self.num_wmasks = 0
|
# self.num_wmasks = 0
|
||||||
#self.set_load_slew(0, 0)
|
#self.set_load_slew(0, 0)
|
||||||
self.set_corner(corner)
|
self.set_corner(corner)
|
||||||
self.create_signal_names()
|
self.create_signal_names()
|
||||||
self.add_graph_exclusions()
|
self.add_graph_exclusions()
|
||||||
self.set_params()
|
self.set_params()
|
||||||
|
|
||||||
def set_params(self):
|
def set_params(self):
|
||||||
"""Set parameters specific to the corner being simulated"""
|
"""Set parameters specific to the corner being simulated"""
|
||||||
self.params = {}
|
self.params = {}
|
||||||
# Set the specific functions to use for timing defined in the SRAM module
|
# Set the specific functions to use for timing defined in the SRAM module
|
||||||
self.params["model_name"] = OPTS.model_name
|
self.params["model_name"] = OPTS.model_name
|
||||||
# Only parameter right now is r_on which is dependent on Vdd
|
# Only parameter right now is r_on which is dependent on Vdd
|
||||||
self.params["r_nch_on"] = self.vdd_voltage / tech.spice["i_on_n"]
|
self.params["r_nch_on"] = self.vdd_voltage / tech.spice["i_on_n"]
|
||||||
self.params["r_pch_on"] = self.vdd_voltage / tech.spice["i_on_p"]
|
self.params["r_pch_on"] = self.vdd_voltage / tech.spice["i_on_p"]
|
||||||
|
|
||||||
def get_lib_values(self, load_slews):
|
def get_lib_values(self, load_slews):
|
||||||
"""
|
"""
|
||||||
Return the analytical model results for the SRAM.
|
Return the analytical model results for the SRAM.
|
||||||
"""
|
"""
|
||||||
if OPTS.num_rw_ports > 1 or OPTS.num_w_ports > 0 and OPTS.num_r_ports > 0:
|
if OPTS.num_rw_ports > 1 or OPTS.num_w_ports > 0 and OPTS.num_r_ports > 0:
|
||||||
debug.warning("In analytical mode, all ports have the timing of the first read port.")
|
debug.warning("In analytical mode, all ports have the timing of the first read port.")
|
||||||
|
|
||||||
# Probe set to 0th bit, does not matter for analytical delay.
|
# Probe set to 0th bit, does not matter for analytical delay.
|
||||||
self.set_probe('0' * self.addr_size, 0)
|
self.set_probe('0' * self.addr_size, 0)
|
||||||
self.create_graph()
|
self.create_graph()
|
||||||
self.set_internal_spice_names()
|
self.set_internal_spice_names()
|
||||||
self.create_measurement_names()
|
self.create_measurement_names()
|
||||||
|
|
||||||
port = self.read_ports[0]
|
port = self.read_ports[0]
|
||||||
self.graph.get_all_paths('{}{}'.format("clk", port),
|
self.graph.get_all_paths('{}{}'.format("clk", port),
|
||||||
'{}{}_{}'.format(self.dout_name, port, self.probe_data))
|
'{}{}_{}'.format(self.dout_name, port, self.probe_data))
|
||||||
|
|
||||||
# Select the path with the bitline (bl)
|
# Select the path with the bitline (bl)
|
||||||
bl_name, br_name = self.get_bl_name(self.graph.all_paths, port)
|
bl_name, br_name = self.get_bl_name(self.graph.all_paths, port)
|
||||||
bl_path = [path for path in self.graph.all_paths if bl_name in path][0]
|
bl_path = [path for path in self.graph.all_paths if bl_name in path][0]
|
||||||
|
|
||||||
# Set delay/power for slews and loads
|
# Set delay/power for slews and loads
|
||||||
port_data = self.get_empty_measure_data_dict()
|
port_data = self.get_empty_measure_data_dict()
|
||||||
power = self.analytical_power(load_slews)
|
power = self.analytical_power(load_slews)
|
||||||
debug.info(1, 'Slew (ns), Load (fF), Delay(ns), Slew(ns)')
|
debug.info(1, 'Slew (ns), Load (fF), Delay(ns), Slew(ns)')
|
||||||
max_delay = 0.0
|
max_delay = 0.0
|
||||||
for load,slew in load_slews:
|
for load,slew in load_slews:
|
||||||
# Calculate delay based on slew and load
|
# Calculate delay based on slew and load
|
||||||
# Calculations expect Farad, input is Femto-Farad
|
# Calculations expect Farad, input is Femto-Farad
|
||||||
load_farad = load*1e-12
|
load_farad = load*1e-12
|
||||||
path_delays = self.graph.get_timing(bl_path, self.corner, slew, load_farad, self.params)
|
load_farad = 0.052275e-12
|
||||||
|
slew = 0
|
||||||
total_delay = self.sum_delays(path_delays)
|
path_delays = self.graph.get_timing(bl_path, self.corner, slew, load_farad, self.params)
|
||||||
delay_ns = total_delay.delay/1e-9
|
|
||||||
slew_ns = total_delay.slew/1e-9
|
total_delay = self.sum_delays(path_delays)
|
||||||
max_delay = max(max_delay, total_delay.delay)
|
debug.info(0, "total_delay={}".format(total_delay))
|
||||||
debug.info(1,'{}, {}, {}, {}'.format(slew,
|
sys.exit()
|
||||||
load,
|
delay_ns = total_delay.delay/1e-9
|
||||||
delay_ns,
|
slew_ns = total_delay.slew/1e-9
|
||||||
slew_ns))
|
max_delay = max(max_delay, total_delay.delay)
|
||||||
# Delay is only calculated on a single port and replicated for now.
|
debug.info(1,'{}, {}, {}, {}'.format(slew,
|
||||||
for port in self.all_ports:
|
load,
|
||||||
for mname in self.delay_meas_names + self.power_meas_names:
|
delay_ns,
|
||||||
if "power" in mname:
|
slew_ns))
|
||||||
port_data[port][mname].append(power.dynamic)
|
# Delay is only calculated on a single port and replicated for now.
|
||||||
elif "delay" in mname and port in self.read_ports:
|
for port in self.all_ports:
|
||||||
port_data[port][mname].append(total_delay.delay / 1e3)
|
for mname in self.delay_meas_names + self.power_meas_names:
|
||||||
elif "slew" in mname and port in self.read_ports:
|
if "power" in mname:
|
||||||
port_data[port][mname].append(total_delay.slew / 1e3)
|
port_data[port][mname].append(power.dynamic)
|
||||||
|
elif "delay" in mname and port in self.read_ports:
|
||||||
# Margin for error in period. Calculated by averaging required margin for a small and large
|
port_data[port][mname].append(total_delay.delay / 1e3)
|
||||||
# memory. FIXME: margin is quite large, should be looked into.
|
elif "slew" in mname and port in self.read_ports:
|
||||||
period_margin = 1.85
|
port_data[port][mname].append(total_delay.slew / 1e3)
|
||||||
sram_data = {"min_period": (max_delay / 1e3) * 2 * period_margin,
|
|
||||||
"leakage_power": power.leakage}
|
# Margin for error in period. Calculated by averaging required margin for a small and large
|
||||||
|
# memory. FIXME: margin is quite large, should be looked into.
|
||||||
debug.info(2, "SRAM Data:\n{}".format(sram_data))
|
period_margin = 1.85
|
||||||
debug.info(2, "Port Data:\n{}".format(port_data))
|
sram_data = {"min_period": (max_delay / 1e3) * 2 * period_margin,
|
||||||
|
"leakage_power": power.leakage}
|
||||||
return (sram_data, port_data)
|
|
||||||
|
debug.info(2, "SRAM Data:\n{}".format(sram_data))
|
||||||
def analytical_power(self, load_slews):
|
debug.info(2, "Port Data:\n{}".format(port_data))
|
||||||
"""Get the dynamic and leakage power from the SRAM"""
|
|
||||||
|
return (sram_data, port_data)
|
||||||
# slews unused, only last load is used
|
|
||||||
load = load_slews[-1][0]
|
def analytical_power(self, load_slews):
|
||||||
power = self.sram.analytical_power(self.corner, load)
|
"""Get the dynamic and leakage power from the SRAM"""
|
||||||
# convert from nW to mW
|
|
||||||
power.dynamic /= 1e6
|
# slews unused, only last load is used
|
||||||
power.leakage /= 1e6
|
load = load_slews[-1][0]
|
||||||
debug.info(1, "Dynamic Power: {0} mW".format(power.dynamic))
|
power = self.sram.analytical_power(self.corner, load)
|
||||||
debug.info(1, "Leakage Power: {0} mW".format(power.leakage))
|
# convert from nW to mW
|
||||||
return power
|
power.dynamic /= 1e6
|
||||||
|
power.leakage /= 1e6
|
||||||
|
debug.info(1, "Dynamic Power: {0} mW".format(power.dynamic))
|
||||||
|
debug.info(1, "Leakage Power: {0} mW".format(power.leakage))
|
||||||
|
return power
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,102 +1,109 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
|
|
||||||
from .simulation import simulation
|
from .simulation import simulation
|
||||||
from globals import OPTS
|
from globals import OPTS
|
||||||
import debug
|
import debug
|
||||||
|
|
||||||
class elmore(simulation):
|
class elmore(simulation):
|
||||||
"""
|
"""
|
||||||
Delay model for the SRAM which calculates Elmore delays along the SRAM critical path.
|
Delay model for the SRAM which calculates Elmore delays along the SRAM critical path.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, sram, spfile, corner):
|
def __init__(self, sram, spfile, corner):
|
||||||
super().__init__(sram, spfile, corner)
|
super().__init__(sram, spfile, corner)
|
||||||
|
|
||||||
# self.targ_read_ports = []
|
# self.targ_read_ports = []
|
||||||
# self.targ_write_ports = []
|
# self.targ_write_ports = []
|
||||||
# self.period = 0
|
# self.period = 0
|
||||||
# if self.write_size:
|
# if self.write_size:
|
||||||
# self.num_wmasks = int(math.ceil(self.word_size / self.write_size))
|
# self.num_wmasks = int(math.ceil(self.word_size / self.write_size))
|
||||||
# else:
|
# else:
|
||||||
# self.num_wmasks = 0
|
# self.num_wmasks = 0
|
||||||
#self.set_load_slew(0, 0)
|
#self.set_load_slew(0, 0)
|
||||||
self.set_corner(corner)
|
self.set_params()
|
||||||
self.create_signal_names()
|
self.set_corner(corner)
|
||||||
self.add_graph_exclusions()
|
self.create_signal_names()
|
||||||
|
self.add_graph_exclusions()
|
||||||
def get_lib_values(self, load_slews):
|
|
||||||
"""
|
def set_params(self):
|
||||||
Return the analytical model results for the SRAM.
|
"""Set parameters specific to the corner being simulated"""
|
||||||
"""
|
self.params = {}
|
||||||
if OPTS.num_rw_ports > 1 or OPTS.num_w_ports > 0 and OPTS.num_r_ports > 0:
|
# Set the specific functions to use for timing defined in the SRAM module
|
||||||
debug.warning("In analytical mode, all ports have the timing of the first read port.")
|
self.params["model_name"] = OPTS.model_name
|
||||||
|
|
||||||
# Probe set to 0th bit, does not matter for analytical delay.
|
def get_lib_values(self, load_slews):
|
||||||
self.set_probe('0' * self.addr_size, 0)
|
"""
|
||||||
self.create_graph()
|
Return the analytical model results for the SRAM.
|
||||||
self.set_internal_spice_names()
|
"""
|
||||||
self.create_measurement_names()
|
if OPTS.num_rw_ports > 1 or OPTS.num_w_ports > 0 and OPTS.num_r_ports > 0:
|
||||||
|
debug.warning("In analytical mode, all ports have the timing of the first read port.")
|
||||||
port = self.read_ports[0]
|
|
||||||
self.graph.get_all_paths('{}{}'.format("clk", port),
|
# Probe set to 0th bit, does not matter for analytical delay.
|
||||||
'{}{}_{}'.format(self.dout_name, port, self.probe_data))
|
self.set_probe('0' * self.addr_size, 0)
|
||||||
|
self.create_graph()
|
||||||
# Select the path with the bitline (bl)
|
self.set_internal_spice_names()
|
||||||
bl_name, br_name = self.get_bl_name(self.graph.all_paths, port)
|
self.create_measurement_names()
|
||||||
bl_path = [path for path in self.graph.all_paths if bl_name in path][0]
|
|
||||||
|
port = self.read_ports[0]
|
||||||
# Set delay/power for slews and loads
|
self.graph.get_all_paths('{}{}'.format("clk", port),
|
||||||
port_data = self.get_empty_measure_data_dict()
|
'{}{}_{}'.format(self.dout_name, port, self.probe_data))
|
||||||
power = self.analytical_power(load_slews)
|
|
||||||
debug.info(1, 'Slew, Load, Delay(ns), Slew(ns)')
|
# Select the path with the bitline (bl)
|
||||||
max_delay = 0.0
|
bl_name, br_name = self.get_bl_name(self.graph.all_paths, port)
|
||||||
for load,slew in load_slews:
|
bl_path = [path for path in self.graph.all_paths if bl_name in path][0]
|
||||||
# Calculate delay based on slew and load
|
|
||||||
path_delays = self.graph.get_timing(bl_path, self.corner, slew, load)
|
# Set delay/power for slews and loads
|
||||||
|
port_data = self.get_empty_measure_data_dict()
|
||||||
total_delay = self.sum_delays(path_delays)
|
power = self.analytical_power(load_slews)
|
||||||
max_delay = max(max_delay, total_delay.delay)
|
debug.info(1, 'Slew, Load, Delay(ns), Slew(ns)')
|
||||||
debug.info(1,
|
max_delay = 0.0
|
||||||
'{}, {}, {}, {}'.format(slew,
|
for load,slew in load_slews:
|
||||||
load,
|
# Calculate delay based on slew and load
|
||||||
total_delay.delay / 1e3,
|
path_delays = self.graph.get_timing(bl_path, self.corner, slew, load, self.params)
|
||||||
total_delay.slew / 1e3))
|
|
||||||
# Delay is only calculated on a single port and replicated for now.
|
total_delay = self.sum_delays(path_delays)
|
||||||
for port in self.all_ports:
|
max_delay = max(max_delay, total_delay.delay)
|
||||||
for mname in self.delay_meas_names + self.power_meas_names:
|
debug.info(1,
|
||||||
if "power" in mname:
|
'{}, {}, {}, {}'.format(slew,
|
||||||
port_data[port][mname].append(power.dynamic)
|
load,
|
||||||
elif "delay" in mname and port in self.read_ports:
|
total_delay.delay / 1e3,
|
||||||
port_data[port][mname].append(total_delay.delay / 1e3)
|
total_delay.slew / 1e3))
|
||||||
elif "slew" in mname and port in self.read_ports:
|
# Delay is only calculated on a single port and replicated for now.
|
||||||
port_data[port][mname].append(total_delay.slew / 1e3)
|
for port in self.all_ports:
|
||||||
|
for mname in self.delay_meas_names + self.power_meas_names:
|
||||||
# Margin for error in period. Calculated by averaging required margin for a small and large
|
if "power" in mname:
|
||||||
# memory. FIXME: margin is quite large, should be looked into.
|
port_data[port][mname].append(power.dynamic)
|
||||||
period_margin = 1.85
|
elif "delay" in mname and port in self.read_ports:
|
||||||
sram_data = {"min_period": (max_delay / 1e3) * 2 * period_margin,
|
port_data[port][mname].append(total_delay.delay / 1e3)
|
||||||
"leakage_power": power.leakage}
|
elif "slew" in mname and port in self.read_ports:
|
||||||
|
port_data[port][mname].append(total_delay.slew / 1e3)
|
||||||
debug.info(2, "SRAM Data:\n{}".format(sram_data))
|
|
||||||
debug.info(2, "Port Data:\n{}".format(port_data))
|
# Margin for error in period. Calculated by averaging required margin for a small and large
|
||||||
|
# memory. FIXME: margin is quite large, should be looked into.
|
||||||
return (sram_data, port_data)
|
period_margin = 1.85
|
||||||
|
sram_data = {"min_period": (max_delay / 1e3) * 2 * period_margin,
|
||||||
def analytical_power(self, load_slews):
|
"leakage_power": power.leakage}
|
||||||
"""Get the dynamic and leakage power from the SRAM"""
|
|
||||||
|
debug.info(2, "SRAM Data:\n{}".format(sram_data))
|
||||||
# slews unused, only last load is used
|
debug.info(2, "Port Data:\n{}".format(port_data))
|
||||||
load = load_slews[-1][0]
|
|
||||||
power = self.sram.analytical_power(self.corner, load)
|
return (sram_data, port_data)
|
||||||
# convert from nW to mW
|
|
||||||
power.dynamic /= 1e6
|
def analytical_power(self, load_slews):
|
||||||
power.leakage /= 1e6
|
"""Get the dynamic and leakage power from the SRAM"""
|
||||||
debug.info(1, "Dynamic Power: {0} mW".format(power.dynamic))
|
|
||||||
debug.info(1, "Leakage Power: {0} mW".format(power.leakage))
|
# slews unused, only last load is used
|
||||||
|
load = load_slews[-1][0]
|
||||||
|
power = self.sram.analytical_power(self.corner, load)
|
||||||
|
# convert from nW to mW
|
||||||
|
power.dynamic /= 1e6
|
||||||
|
power.leakage /= 1e6
|
||||||
|
debug.info(1, "Dynamic Power: {0} mW".format(power.dynamic))
|
||||||
|
debug.info(1, "Leakage Power: {0} mW".format(power.leakage))
|
||||||
return power
|
return power
|
||||||
Loading…
Reference in New Issue