diff --git a/compiler/characterizer/delay.py b/compiler/characterizer/delay.py index 758d7af1..93b7c983 100644 --- a/compiler/characterizer/delay.py +++ b/compiler/characterizer/delay.py @@ -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": diff --git a/compiler/characterizer/simulation.py b/compiler/characterizer/simulation.py index 2dec0010..1e6a34ab 100644 --- a/compiler/characterizer/simulation.py +++ b/compiler/characterizer/simulation.py @@ -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): """ diff --git a/compiler/characterizer/trim_spice.py b/compiler/characterizer/trim_spice.py index e3892d9d..603934c0 100644 --- a/compiler/characterizer/trim_spice.py +++ b/compiler/characterizer/trim_spice.py @@ -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)