mirror of https://github.com/VLSIDA/OpenRAM.git
Recover function for measures
This commit is contained in:
parent
6603220258
commit
816eff711d
|
|
@ -17,6 +17,8 @@ from .bit_polarity import *
|
|||
from globals import OPTS
|
||||
from .simulation import simulation
|
||||
from .measurements import *
|
||||
from os import path
|
||||
import re
|
||||
|
||||
|
||||
class delay(simulation):
|
||||
|
|
@ -118,6 +120,8 @@ class delay(simulation):
|
|||
# Other measurements associated with the read port not included in the liberty file
|
||||
read_measures.append(self.create_bitline_measurement_objects())
|
||||
read_measures.append(self.create_debug_measurement_objects())
|
||||
# TODO: Maybe don't do this here (?)
|
||||
if OPTS.top_process != "memchar":
|
||||
read_measures.append(self.create_read_bit_measures())
|
||||
read_measures.append(self.create_sen_and_bitline_path_measures())
|
||||
|
||||
|
|
@ -245,8 +249,8 @@ class delay(simulation):
|
|||
def create_sen_and_bitline_path_measures(self):
|
||||
"""Create measurements for the s_en and bitline paths for individual delays per stage."""
|
||||
|
||||
# FIXME: There should be a default_read_port variable in this case, pathing is done with this
|
||||
# but is never mentioned otherwise
|
||||
# # FIXME: There should be a default_read_port variable in this case, pathing is done with this
|
||||
# # but is never mentioned otherwise
|
||||
port = self.read_ports[0]
|
||||
sen_and_port = self.sen_name + str(port)
|
||||
bl_and_port = self.bl_name.format(port) # bl_name contains a '{}' for the port
|
||||
|
|
@ -391,12 +395,12 @@ class delay(simulation):
|
|||
|
||||
# creates and opens stimulus file for writing
|
||||
self.delay_stim_sp = "delay_stim.sp"
|
||||
temp_stim = "{0}/{1}".format(self.output_path, self.delay_stim_sp)
|
||||
temp_stim = path.join(self.output_path, self.delay_stim_sp)
|
||||
self.sf = open(temp_stim, "w")
|
||||
|
||||
# creates and opens measure file for writing
|
||||
self.delay_meas_sp = "delay_meas.sp"
|
||||
temp_meas = "{0}/{1}".format(self.output_path, self.delay_meas_sp)
|
||||
temp_meas = path.join(self.output_path, self.delay_meas_sp)
|
||||
self.mf = open(temp_meas, "w")
|
||||
|
||||
if OPTS.spice_name == "spectre":
|
||||
|
|
@ -429,7 +433,7 @@ class delay(simulation):
|
|||
t_rise=self.slew,
|
||||
t_fall=self.slew)
|
||||
|
||||
self.stim.write_include(temp_meas)
|
||||
self.sf.write(".include {0}".format(temp_meas))
|
||||
# self.load_all_measure_nets()
|
||||
self.write_delay_measures()
|
||||
# self.write_simulation_saves()
|
||||
|
|
@ -448,15 +452,15 @@ class delay(simulation):
|
|||
|
||||
# creates and opens stimulus file for writing
|
||||
self.power_stim_sp = "power_stim.sp"
|
||||
temp_stim = "{0}/{1}".format(self.output_path, self.power_stim_sp)
|
||||
temp_stim = path.join(self.output_path, self.power_stim_sp)
|
||||
self.sf = open(temp_stim, "w")
|
||||
self.sf.write("* Power stimulus for period of {0}n\n\n".format(self.period))
|
||||
self.stim = stimuli(self.sf, self.corner)
|
||||
|
||||
# creates and opens measure file for writing
|
||||
self.power_meas_sp = "power_meas.sp"
|
||||
temp_meas = "{0}/{1}".format(opts.openram_temp, self.power_meas_sp)
|
||||
temp_meas = path.join(self.output_path, self.power_meas_sp)
|
||||
self.mf = open(temp_meas, "w")
|
||||
self.stim = stimuli(self.sf, self.mf, self.corner)
|
||||
|
||||
# include UNTRIMMED files in stimulus file
|
||||
if trim:
|
||||
|
|
@ -488,7 +492,7 @@ class delay(simulation):
|
|||
for port in self.all_ports:
|
||||
self.stim.gen_constant(sig_name="CLK{0}".format(port), v_val=0)
|
||||
|
||||
self.stim.write_include(temp_meas)
|
||||
self.sf.write(".include {}".format(temp_meas))
|
||||
self.write_power_measures()
|
||||
|
||||
# run until the end of the cycle time
|
||||
|
|
@ -1151,11 +1155,86 @@ class delay(simulation):
|
|||
if self.sp_file != self.sim_sp_file:
|
||||
shutil.copy(self.sp_file, self.sim_sp_file)
|
||||
|
||||
def recover_measurment_objects(self):
|
||||
mf = open(path.join(OPTS.output_path, "delay_meas.sp"), "r")
|
||||
measure_text = mf.read()
|
||||
port_iter = re.finditer(r"\* (Read|Write) ports (\d*)", measure_text)
|
||||
port_measure_lines = []
|
||||
loc = 0
|
||||
port_name = ''
|
||||
for port in port_iter:
|
||||
port_measure_lines.append((port_name, measure_txt[loc:port.end(0)]))
|
||||
loc = port.start(0)
|
||||
port_name = port.group(1) + port.group(2)
|
||||
|
||||
mf.close()
|
||||
# Cycle comments, not sure if i need this
|
||||
cycle_lines = port_measure_lines.pop(0)[1]
|
||||
# For now just recover the bit_measures and sen_and_bitline_path_measures
|
||||
self.read_meas_lists.append([])
|
||||
bit_measure_rule = re.compile(r"\.meas tran (v_q_a\d+_b\d+_(read|write)_(zero|one)\d+) FIND v\((.*)\) AT=(\d+(\.\d+)?)n")
|
||||
for measures in port_measure_lines:
|
||||
port_name = measures[0]
|
||||
text = measures[1]
|
||||
bit_measure_iter = bit_measure_rule.finditer(text)
|
||||
for bit_measure in bit_measure_iter:
|
||||
meas_name = bit_measure.group(1)
|
||||
read = bit_measure.group(2) == "read"
|
||||
probe = bit_measure.group(4)
|
||||
polarity = bit_polarity.NONINVERTING
|
||||
if "q_bar" in meas_name:
|
||||
polarity = bit_polarity.INVERTING
|
||||
meas = voltage_at_measure(meas_name, probe)
|
||||
if read:
|
||||
self.read_bit_meas[polarity].append(meas)
|
||||
self.read_meas_lists[-1].append(meas)
|
||||
else:
|
||||
self.write_bit_meas[polarity].append(meas)
|
||||
self.write_meas_lists[-1].append(meas)
|
||||
|
||||
delay_path_rule = re.compile(r"\.meas tran delay_(.*)_to_(.*) TRIG v\((.*)\) VAL=(\d+(\.\d+)?) (RISE|FALL)=(\d+) TD=(\d+(\.\d+)?)n TARG v\((.*)\) VAL=(\d+(\.\d+)?) (RISE|FALL)=(\d+) TD=(\d+(\.\d+)?)n")
|
||||
port = self.read_ports[0]
|
||||
sen_and_port = self.sen_name + str(port)
|
||||
bl_and_port = self.bl_name.format(port) # bl_name contains a '{}' for the port
|
||||
meas_buff = []
|
||||
for measures in port_measure_lines:
|
||||
port_name = measures[0]
|
||||
text = measures[1]
|
||||
delay_path_iter = delay_path_rule.finditer(text)
|
||||
for delay_path_measure in delay_path_iter:
|
||||
from_ = delay_path_measure.group(1)
|
||||
to_ = delay_path_measure.group(2)
|
||||
trig_rise = delay_path_measure.group(5)
|
||||
targ_rise = delay_path_measure.group(10)
|
||||
meas_name = "delay_{0}_to_{1}".format(from_, to_)
|
||||
meas = delay_measure(meas_name, from_, to_, trig_rise, targ_rise, measure_scale=1e9, has_port=False)
|
||||
meas.meta_str = sram_op.READ_ZERO
|
||||
meas.meta_add_delay = True
|
||||
meas_buff.append(meas)
|
||||
# TODO: we are losing duplicate measures here
|
||||
if from_ == sen_and_port:
|
||||
self.sen_path_meas.extend(meas_buff.copy())
|
||||
meas_buff.clear()
|
||||
elif from_ == bl_and_port:
|
||||
self.bl_path_meas.extend(meas_buff)
|
||||
meas_buff.clear()
|
||||
self.read_meas_lists.append(self.sen_path_meas + self.bl_path_meas)
|
||||
|
||||
|
||||
|
||||
def analysis_init(self, probe_address, probe_data):
|
||||
"""Sets values which are dependent on the data address/bit being tested."""
|
||||
|
||||
self.set_probe(probe_address, probe_data)
|
||||
self.prepare_netlist()
|
||||
if OPTS.top_process == "memchar":
|
||||
# TODO: fix
|
||||
self.bl_name = "xsram.xbank0.bl_0_{}"
|
||||
self.br_name = "xsram.xbank0.br_0_{}"
|
||||
self.sen_name = "xsram.s_en"
|
||||
self.create_measurement_objects()
|
||||
self.recover_measurment_objects()
|
||||
else:
|
||||
self.create_graph()
|
||||
self.set_internal_spice_names()
|
||||
self.create_measurement_names()
|
||||
|
|
|
|||
|
|
@ -10,9 +10,14 @@ class fake_sram(sram_config):
|
|||
"""
|
||||
def __init__(self, name, word_size, num_words, write_size=None, num_banks=1,
|
||||
words_per_row=None, num_spare_rows=0, num_spare_cols=0):
|
||||
sram_config.__init__(self, name, word_size, num_words, write_size=None,
|
||||
num_banks=1, words_per_row=None, num_spare_rows=0,
|
||||
num_spare_cols=0)
|
||||
sram_config.__init__(self, word_size, num_words, write_size,
|
||||
num_banks, words_per_row, num_spare_rows,
|
||||
num_spare_cols)
|
||||
self.name = name
|
||||
if write_size and self.write_size != self.word_size:
|
||||
self.num_wmasks = int(ceil(self.word_size / self.write_size))
|
||||
else:
|
||||
self.num_wmasks = 0
|
||||
|
||||
def setup_multiport_constants(self):
|
||||
"""
|
||||
|
|
@ -88,35 +93,36 @@ class fake_sram(sram_config):
|
|||
self.pins.extend(['clk{}'.format(port) for port in range(
|
||||
self.num_rw_ports + self.num_r_ports + self.num_w_ports)])
|
||||
for port in range(self.num_rw_ports):
|
||||
self.pins.extend(['din{0}[{1}]]'.format(port, bit)
|
||||
self.pins.extend(['din{0}[{1}]'.format(port, bit)
|
||||
for bit in range(self.num_cols)])
|
||||
self.pins.extend(['dout{0}[{1}]]'.format(port, bit)
|
||||
self.pins.extend(['dout{0}[{1}]'.format(port, bit)
|
||||
for bit in range(self.num_cols)])
|
||||
self.pins.extend(['addr{0}[{1}]]'.format(port, bit)
|
||||
self.pins.extend(['addr{0}[{1}]'.format(port, bit)
|
||||
for bit in range(self.addr_size)])
|
||||
if self.num_wmasks != 0:
|
||||
self.pins.extend(['wmask{0}[{1}]]'.format(port, bit)
|
||||
print(self.num_wmasks)
|
||||
self.pins.extend(['wmask{0}[{1}]'.format(port, bit)
|
||||
for bit in range(self.num_wmasks)])
|
||||
|
||||
self.pins.extend(['csb{}'.format(port), 'web{}'.format(port)])
|
||||
|
||||
start_port = self.num_rw_ports
|
||||
for port in range(start_port, start_port + self.num_r_ports):
|
||||
self.pins.extend(['dout{0}[{1}]]'.format(port, bit)
|
||||
self.pins.extend(['dout{0}[{1}]'.format(port, bit)
|
||||
for bit in range(self.num_cols)])
|
||||
self.pins.extend(['addr{0}[{1}]]'.format(port, bit)
|
||||
self.pins.extend(['addr{0}[{1}]'.format(port, bit)
|
||||
for bit in range(self.addr_size)])
|
||||
|
||||
self.pins.extend(['csb{}'.format(port)])
|
||||
|
||||
start_port += self.num_r_ports
|
||||
for port in range(start_port, start_port + self.num_w_ports):
|
||||
self.pins.extend(['din{0}[{1}]]'.format(port, bit)
|
||||
self.pins.extend(['din{0}[{1}]'.format(port, bit)
|
||||
for bit in range(self.num_cols)])
|
||||
self.pins.extend(['addr{0}[{1}]]'.format(port, bit)
|
||||
self.pins.extend(['addr{0}[{1}]'.format(port, bit)
|
||||
for bit in range(self.addr_size)])
|
||||
if self.num_wmasks != 0:
|
||||
self.pins.extend(['wmask{0}[{1}]]'.format(port, bit)
|
||||
self.pins.extend(['wmask{0}[{1}]'.format(port, bit)
|
||||
for bit in range(self.num_wmasks)])
|
||||
|
||||
self.pins.extend(['csb{}'.format(port), 'web{}'.format(port)])
|
||||
|
|
|
|||
Loading…
Reference in New Issue