Fix address bit ordering in sky130 1rw characterization

This commit is contained in:
rlin50 2026-02-23 15:32:08 -08:00
parent ec28bc6dfd
commit 6d14626a75
3 changed files with 24 additions and 9 deletions

View File

@ -1388,11 +1388,15 @@ class delay(simulation):
def calculate_inverse_address(self):
"""Determine dummy test address based on probe address and column mux size."""
# The inverse address needs to share the same bitlines as the probe address as the trimming will remove all other bitlines
# The inverse address needs to share the same bitlines as the probe address as the trimming will remove all other bitlines.
# This is only an issue when there is a column mux and the address maps to different bitlines.
column_addr = self.get_column_addr() # do not invert this part
inverse_address = ""
for c in self.probe_address[self.sram.col_addr_size:]: # invert everything else
if self.sram.col_addr_size > 0:
row_address = self.probe_address[:-self.sram.col_addr_size]
else:
row_address = self.probe_address
for c in row_address: # invert row bits only
if c=="0":
inverse_address += "1"
elif c=="1":

View File

@ -126,8 +126,10 @@ class simulation():
def get_data_bit_column_number(self, probe_address, probe_data):
"""Calculates bitline column number of data bit under test using bit position and mux size"""
if self.sram.col_addr_size>0:
col_address = int(probe_address[0:self.sram.col_addr_size], 2)
# Address pins are ordered a*_0 ... a*_N, where a*_0 is the LSB.
# So the column mux select bits are the rightmost bits in the binary address string.
if self.sram.col_addr_size > 0:
col_address = int(probe_address[-self.sram.col_addr_size:], 2)
else:
col_address = 0
bl_column = int(self.sram.words_per_row * probe_data + col_address)
@ -136,7 +138,11 @@ class simulation():
def get_address_row_number(self, probe_address):
"""Calculates wordline row number of data bit under test using address and column mux size"""
return int(probe_address[self.sram.col_addr_size:], 2)
if self.sram.col_addr_size > 0:
row_address = probe_address[:-self.sram.col_addr_size]
else:
row_address = probe_address
return int(row_address, 2) if row_address else 0
def add_control_one_port(self, port, op):
"""Appends control signals for operation to a given port"""
@ -484,7 +490,9 @@ class simulation():
def get_column_addr(self):
"""Returns column address of probe bit"""
return self.probe_address[:self.sram.col_addr_size]
if self.sram.col_addr_size == 0:
return ""
return self.probe_address[-self.sram.col_addr_size:]
def add_graph_exclusions(self):
"""

View File

@ -56,12 +56,15 @@ class trim_spice():
# Always start fresh if we do multiple reductions
self.sp_buffer = self.spice
# Split up the address and convert to an int
wl_address = int(address[self.col_addr_size:], 2)
# Address pins are ordered with bit 0 as LSB, so mux column bits
# are the rightmost bits in the binary address string.
if self.col_addr_size > 0:
col_address = int(address[0:self.col_addr_size], 2)
row_address = address[:-self.col_addr_size]
col_address = int(address[-self.col_addr_size:], 2)
else:
row_address = address
col_address = 0
wl_address = int(row_address, 2) if row_address else 0
# 1. Keep cells in the bitcell array based on WL and BL
wl_name = "wl_{}".format(wl_address)