modify char to work with older macro

This commit is contained in:
Bugra Onal 2023-01-19 11:39:16 -08:00
parent 8a67626e55
commit 7fdc5cc782
5 changed files with 61 additions and 49 deletions

View File

@ -121,9 +121,9 @@ class delay(simulation):
# Other measurements associated with the read port not included in the liberty file # 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_bitline_measurement_objects())
read_measures.append(self.create_debug_measurement_objects()) read_measures.append(self.create_debug_measurement_objects())
read_measures.append(self.create_read_bit_measures())
# TODO: Maybe don't do this here (?) # TODO: Maybe don't do this here (?)
if OPTS.top_process != "memchar": if OPTS.top_process != "memchar":
read_measures.append(self.create_read_bit_measures())
read_measures.append(self.create_sen_and_bitline_path_measures()) read_measures.append(self.create_sen_and_bitline_path_measures())
return read_measures return read_measures
@ -168,7 +168,6 @@ class delay(simulation):
write_measures = [] write_measures = []
write_measures.append(self.write_lib_meas) write_measures.append(self.write_lib_meas)
if OPTS.top_process != "memchar":
write_measures.append(self.create_write_bit_measures()) write_measures.append(self.create_write_bit_measures())
return write_measures return write_measures
@ -229,8 +228,11 @@ class delay(simulation):
bit_col = self.get_data_bit_column_number(probe_address, probe_data) bit_col = self.get_data_bit_column_number(probe_address, probe_data)
bit_row = self.get_address_row_number(probe_address) bit_row = self.get_address_row_number(probe_address)
(cell_name, cell_inst) = self.sram.get_cell_name(self.sram.name, bit_row, bit_col) #(cell_name, cell_inst) = self.sram.get_cell_name(self.sram.name, bit_row, bit_col)
storage_names = cell_inst.mod.get_storage_net_names() cell_name = OPTS.hier_seperator.join(("X" + self.sram.name, "xbank0", "xreplica_bitcell_array", "xbitcell_array", "xbit_r{}_c{}".format(bit_row, bit_col)))
#cell_name = OPTS.hier_seperator.join(("X" + self.sram.name, "xbank0", "xbitcell_array", "xbitcell_array", "xbit_r{}_c{}".format(bit_row, bit_col)))
storage_names = ("Q", "Q_bar")
#storage_names = cell_inst.mod.get_storage_net_names()
debug.check(len(storage_names) == 2, ("Only inverting/non-inverting storage nodes" debug.check(len(storage_names) == 2, ("Only inverting/non-inverting storage nodes"
"supported for characterization. Storage nets={0}").format(storage_names)) "supported for characterization. Storage nets={0}").format(storage_names))
if OPTS.use_pex and OPTS.pex_exe[0] != "calibre": if OPTS.use_pex and OPTS.pex_exe[0] != "calibre":
@ -859,6 +861,7 @@ class delay(simulation):
result[port].update(read_port_dict) result[port].update(read_port_dict)
if self.sen_path_meas and self.bl_path_meas:
self.path_delays = self.check_path_measures() self.path_delays = self.check_path_measures()
return (True, result) return (True, result)
@ -950,7 +953,7 @@ class delay(simulation):
def check_bitline_meas(self, v_discharged_bl, v_charged_bl): def check_bitline_meas(self, v_discharged_bl, v_charged_bl):
""" """
Checks the value of the discharging bitline. Confirms s_en timing errors. Checks the value of the discharging bitline. Confirms s_en timing errors.
Returns true if the bitlines are at there expected value. Returns true if the bitlines are at there their value.
""" """
# The inputs looks at discharge/charged bitline rather than left or right (bl/br) # The inputs looks at discharge/charged bitline rather than left or right (bl/br)
# Performs two checks, discharging bitline is at least 10% away from vdd and there is a # Performs two checks, discharging bitline is at least 10% away from vdd and there is a
@ -1161,7 +1164,13 @@ class delay(simulation):
shutil.copy(self.sp_file, self.sim_sp_file) shutil.copy(self.sp_file, self.sim_sp_file)
def recover_measurment_objects(self): def recover_measurment_objects(self):
mf = open(path.join(OPTS.output_path, "delay_meas.sp"), "r") mf_path = path.join(OPTS.output_path, "delay_meas.sp")
self.sen_path_meas = None
self.bl_path_meas = None
if not path.exists(mf_path):
debug.info(1, "Delay measure file not found. Skipping measure recovery")
return
mf = open(mf_path, "r")
measure_text = mf.read() measure_text = mf.read()
port_iter = re.finditer(r"\* (Read|Write) ports (\d*)", measure_text) port_iter = re.finditer(r"\* (Read|Write) ports (\d*)", measure_text)
port_measure_lines = [] port_measure_lines = []
@ -1179,34 +1188,34 @@ class delay(simulation):
self.read_meas_lists.append([]) self.read_meas_lists.append([])
self.read_bit_meas = {bit_polarity.NONINVERTING: [], bit_polarity.INVERTING: []} self.read_bit_meas = {bit_polarity.NONINVERTING: [], bit_polarity.INVERTING: []}
self.write_bit_meas = {bit_polarity.NONINVERTING: [], bit_polarity.INVERTING: []} self.write_bit_meas = {bit_polarity.NONINVERTING: [], bit_polarity.INVERTING: []}
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") # 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: # for measures in port_measure_lines:
port_name = measures[0] # port_name = measures[0]
text = measures[1] # text = measures[1]
bit_measure_iter = bit_measure_rule.finditer(text) # bit_measure_iter = bit_measure_rule.finditer(text)
for bit_measure in bit_measure_iter: # for bit_measure in bit_measure_iter:
meas_name = bit_measure.group(1) # meas_name = bit_measure.group(1)
read = bit_measure.group(2) == "read" # read = bit_measure.group(2) == "read"
cycle = bit_measure.group(3) # cycle = bit_measure.group(3)
probe = bit_measure.group(4) # probe = bit_measure.group(4)
polarity = bit_polarity.NONINVERTING # polarity = bit_polarity.NONINVERTING
if "q_bar" in meas_name: # if "q_bar" in meas_name:
polarity = bit_polarity.INVERTING # polarity = bit_polarity.INVERTING
meas = voltage_at_measure(meas_name, probe) # meas = voltage_at_measure(meas_name, probe)
if read: # if read:
if cycle == "one": # if cycle == "one":
meas.meta_str = sram_op.READ_ONE # meas.meta_str = sram_op.READ_ONE
else: # else:
meas.meta_str = sram_op.READ_ZERO # meas.meta_str = sram_op.READ_ZERO
self.read_bit_meas[polarity].append(meas) # self.read_bit_meas[polarity].append(meas)
self.read_meas_lists[-1].append(meas) # self.read_meas_lists[-1].append(meas)
else: # else:
if cycle == "one": # if cycle == "one":
meas.meta_str = sram_op.WRITE_ONE # meas.meta_str = sram_op.WRITE_ONE
else: # else:
meas.meta_str = sram_op.WRITE_ZERO # meas.meta_str = sram_op.WRITE_ZERO
self.write_bit_meas[polarity].append(meas) # self.write_bit_meas[polarity].append(meas)
self.write_meas_lists[-1].append(meas) # self.write_meas_lists[-1].append(meas)
delay_path_rule = re.compile(r"\.meas tran delay_(.*)_to_(.*)_(sen|bl)_(id\d*) TRIG v\((.*)\) VAL=(\d+(\.\d+)?) (RISE|FALL)=(\d+) TD=(\d+(\.\d+)?)n TARG v\((.*)\) VAL=(\d+(\.\d+)?) (RISE|FALL)=(\d+) TD=(\d+(\.\d+)?)n") delay_path_rule = re.compile(r"\.meas tran delay_(.*)_to_(.*)_(sen|bl)_(id\d*) 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] port = self.read_ports[0]
@ -1244,10 +1253,10 @@ class delay(simulation):
self.set_probe(probe_address, probe_data) self.set_probe(probe_address, probe_data)
self.prepare_netlist() self.prepare_netlist()
if OPTS.top_process == "memchar": if OPTS.top_process == "memchar":
# TODO: fix # TODO: guess the bl and br. It can be "bl_..." or "bl..."
self.bl_name = "xsram:xbank0:bl_0_{}" self.bl_name = "X{0}{1}xbank0{1}bl{{}}_{2}".format(self.sram.name, OPTS.hier_seperator, self.bitline_column)
self.br_name = "xsram:xbank0:br_0_{}" self.br_name = "X{0}{1}xbank0{1}br{{}}_{2}".format(self.sram.name, OPTS.hier_seperator, self.bitline_column)
self.sen_name = "xsram:s_en" self.sen_name = "X{0}{1}xbank0{1}s_en".format(self.sram.name, OPTS.hier_seperator)
self.create_measurement_objects() self.create_measurement_objects()
self.recover_measurment_objects() self.recover_measurment_objects()
else: else:
@ -1522,3 +1531,6 @@ class delay(simulation):
self.stim.gen_pwl("CSB{0}".format(port), self.cycle_times, self.csb_values[port], self.period, self.slew, 0.05) self.stim.gen_pwl("CSB{0}".format(port), self.cycle_times, self.csb_values[port], self.period, self.slew, 0.05)
if port in self.readwrite_ports: if port in self.readwrite_ports:
self.stim.gen_pwl("WEB{0}".format(port), self.cycle_times, self.web_values[port], self.period, self.slew, 0.05) self.stim.gen_pwl("WEB{0}".format(port), self.cycle_times, self.web_values[port], self.period, self.slew, 0.05)
if self.sram.num_wmasks:
for bit in range(self.sram.num_wmasks):
self.stim.gen_pwl("WMASK{0}_{1}".format(port, bit), self.cycle_times, self.wmask_values[port][bit], self.period, self.slew, 0.05)

View File

@ -94,13 +94,12 @@ class fake_sram(sram_config):
self.num_rw_ports + self.num_r_ports + self.num_w_ports)]) self.num_rw_ports + self.num_r_ports + self.num_w_ports)])
for port in range(self.num_rw_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)]) for bit in range(self.word_size)])
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)]) for bit in range(self.word_size)])
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)]) for bit in range(self.addr_size)])
if self.num_wmasks != 0: if self.num_wmasks != 0:
print(self.num_wmasks)
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)]) for bit in range(self.num_wmasks)])
@ -109,7 +108,7 @@ class fake_sram(sram_config):
start_port = self.num_rw_ports start_port = self.num_rw_ports
for port in range(start_port, start_port + self.num_r_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)]) for bit in range(self.word_size)])
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)]) for bit in range(self.addr_size)])
@ -118,7 +117,7 @@ class fake_sram(sram_config):
start_port += self.num_r_ports start_port += self.num_r_ports
for port in range(start_port, start_port + self.num_w_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)]) for bit in range(self.word_size)])
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)]) for bit in range(self.addr_size)])
if self.num_wmasks != 0: if self.num_wmasks != 0:

View File

@ -299,10 +299,11 @@ class functional(simulation):
self.v_low, self.v_low,
self.v_high) self.v_high)
except ValueError: except ValueError:
error ="FAILED: {0}_{1} value {2} at time {3}n is not a float.".format(dout_port, error ="FAILED: {0}_{1} value {2} at time {3}n is not a float. Measure: {4}".format(dout_port,
bit, bit,
value, value,
eo_period) eo_period,
measure_name)
return (0, error) return (0, error)
self.read_results.append([sp_read_value, dout_port, eo_period, cycle]) self.read_results.append([sp_read_value, dout_port, eo_period, cycle])

View File

@ -42,7 +42,7 @@ class setup_hold():
self.stim_sp = "sh_stim.sp" self.stim_sp = "sh_stim.sp"
temp_stim = OPTS.openram_temp + self.stim_sp temp_stim = OPTS.openram_temp + self.stim_sp
self.sf = open(temp_stim, "w") self.sf = open(temp_stim, "w")
self.stim = stimuli(self.sf, self.corner) self.stim = stimuli(self.sf, self.mf, self.corner)
self.write_header(correct_value) self.write_header(correct_value)

View File

@ -55,7 +55,7 @@ s = fake_sram(name=OPTS.output_name,
num_spare_rows=OPTS.num_spare_rows, num_spare_rows=OPTS.num_spare_rows,
num_spare_cols=OPTS.num_spare_cols) num_spare_cols=OPTS.num_spare_cols)
s.parse_html(OPTS.output_path + "sram.html") s.parse_html(OPTS.output_path + s.name + ".html")
s.generate_pins() s.generate_pins()
s.setup_multiport_constants() s.setup_multiport_constants()