Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions compiler/characterizer/delay.py
Original file line number Diff line number Diff line change
Expand Up @@ -1388,11 +1388,15 @@ def get_delay_lists(self, value_dict):
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":
Expand Down
16 changes: 12 additions & 4 deletions compiler/characterizer/simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,10 @@ def set_probe(self, probe_address, probe_data):
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)
Expand All @@ -136,7 +138,11 @@ def get_data_bit_column_number(self, probe_address, probe_data):
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"""
Expand Down Expand Up @@ -484,7 +490,9 @@ def gen_pin_names(self, port_signal_names, port_info, abits, dbits):

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):
"""
Expand Down
9 changes: 6 additions & 3 deletions compiler/characterizer/trim_spice.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,15 @@ def trim(self, address, data_bit):
# 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)
Expand Down
9 changes: 5 additions & 4 deletions technology/sky130/custom/sky130_bitcell_base_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,14 +100,15 @@ def get_col_cap_pins(self, row, col):
strap_pins = []
for port in self.all_ports:
strap_pins.extend([x for x in self.get_bitline_names(port) if "bl" in x and x.endswith("_{0}".format(col))])
strap_pins.extend(["vdd", "gnd"])
for port in self.all_ports:
strap_pins.extend([x for x in self.get_bitline_names(port) if "br" in x and x.endswith("_{0}".format(col))])
# col_cap_1port_bitcell port order:
# [bl, br, vdd, gnd, vpb, vnb, gate]
strap_pins.extend(["vdd", "gnd", "vdd", "gnd"])
if row == 0:
strap_pins.extend(["top_gate"])
strap_pins.append("top_gate")
else:
strap_pins.extend(["bot_gate"])
strap_pins.extend(["vdd", "gnd"])
strap_pins.append("bot_gate")
return strap_pins

def get_row_cap_pins(self, row, col):
Expand Down
8 changes: 4 additions & 4 deletions technology/sky130/custom/sky130_col_cap_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,12 @@ def create_instances(self):
row_layout.append(self.colend1)
self.cell_inst[col]=self.add_inst(name=name, mod=self.colend1)
pins.append("fake_bl_{}".format(bitline))
pins.append("fake_br_{}".format(bitline))
pins.append("vdd")
pins.append("gnd")
pins.append("fake_br_{}".format(bitline))
pins.append("gate")
pins.append("vdd")
pins.append("gnd")
pins.append("gate")
bitline += 1
elif col % 4 == 1:
row_layout.append(self.colend2)
Expand All @@ -92,12 +92,12 @@ def create_instances(self):
row_layout.append(self.colend1)
self.cell_inst[col]=self.add_inst(name=name, mod=self.colend1)
pins.append("fake_bl_{}".format(bitline))
pins.append("fake_br_{}".format(bitline))
pins.append("vdd")
pins.append("gnd")
pins.append("fake_br_{}".format(bitline))
pins.append("gate")
pins.append("vdd")
pins.append("gnd")
pins.append("gate")
bitline += 1
elif col % 4 ==3:
row_layout.append(self.colend2)
Expand Down