mirror of https://github.com/VLSIDA/OpenRAM.git
passing code style
This commit is contained in:
parent
79efff9ca6
commit
af0209ec96
|
|
@ -703,7 +703,7 @@ class layout():
|
|||
bins = {}
|
||||
for pin in pins:
|
||||
y = pin.cy()
|
||||
if round:
|
||||
if round:
|
||||
y = round_to_grid(y)
|
||||
try:
|
||||
bins[y].append(pin)
|
||||
|
|
@ -794,7 +794,7 @@ class layout():
|
|||
bins = {}
|
||||
for pin in pins:
|
||||
x = pin.cx()
|
||||
if round:
|
||||
if round:
|
||||
x = round_to_grid(x)
|
||||
try:
|
||||
bins[x].append(pin)
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ class pinvbuf(pgate):
|
|||
# end_point = vector(a4_pin.cx(), a4_pin.by() - self.m1_space - self.contact_space)
|
||||
self.add_path(route_stack[2],
|
||||
[z1_pin.center(), mid_point, end_point])
|
||||
|
||||
|
||||
self.add_via_stack_center(from_layer=z1_pin.layer,
|
||||
to_layer=route_stack[2],
|
||||
offset=z1_pin.center())
|
||||
|
|
@ -151,11 +151,11 @@ class pinvbuf(pgate):
|
|||
to_layer=route_stack[2],
|
||||
offset=end_point)
|
||||
|
||||
|
||||
|
||||
self.add_segment_center(a4_pin.layer, end_point, a4_pin.center())
|
||||
else:
|
||||
# inv1 Z to inv4 A (up and over)
|
||||
|
||||
|
||||
mid_point = vector(z1_pin.cx(), a4_pin.cy())
|
||||
self.add_wire(route_stack,
|
||||
[z1_pin.center(), mid_point, a4_pin.center()])
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ class rom_address_control_array(design):
|
|||
name = "rom_inv_array_{0}".format(cols)
|
||||
if inv_height == None:
|
||||
self.inv_height = dff.height * 0.5
|
||||
else:
|
||||
else:
|
||||
self.inv_height = inv_height
|
||||
|
||||
|
||||
|
|
@ -46,7 +46,7 @@ class rom_address_control_array(design):
|
|||
|
||||
def create_layout(self):
|
||||
self.width = self.cols * self.addr_control.width
|
||||
self.height = self.addr_control.height
|
||||
self.height = self.addr_control.height
|
||||
self.setup_layout_constants()
|
||||
self.place_instances()
|
||||
self.route_clk()
|
||||
|
|
|
|||
|
|
@ -130,8 +130,6 @@ class rom_address_control_buf(design):
|
|||
self.add_via_stack_center(from_layer=self.inv_layer, to_layer=self.route_layer, offset=self.addr_bar_nand.get_pin("A").center())
|
||||
self.add_segment_center(self.route_layer, clk_offset, vector(clk_offset.x, clk2_pin.cy()))
|
||||
|
||||
|
||||
|
||||
# Route first NAND output to second NAND input
|
||||
start = A_out.center()
|
||||
end = Aint_in.center()
|
||||
|
|
@ -139,18 +137,15 @@ class rom_address_control_buf(design):
|
|||
self.add_via_stack_center(Aint_in.center(), self.inv_layer, "m2")
|
||||
self.add_via_stack_center(A_out.center(), self.inv_layer, "m2")
|
||||
|
||||
|
||||
# Route first NAND to output pin
|
||||
self.add_segment_center("m2", end, vector(end.x, self.addr_bar_nand.uy()))
|
||||
self.add_layout_pin_rect_center("A_out", offset=vector(end.x, self.addr_bar_nand.uy() - 0.5 * self.m2_width), layer="m2")
|
||||
|
||||
|
||||
# Route second NAND to output pin
|
||||
self.add_via_stack_center(Abar_out.center(), self.inv_layer, "m2")
|
||||
self.add_segment_center("m2", Abar_out.center(), vector(Abar_out.cx(), self.addr_bar_nand.uy()))
|
||||
self.add_layout_pin_rect_center("Abar_out", offset=vector(Abar_out.cx(), self.addr_bar_nand.uy() - 0.5 * self.m2_width), layer="m2")
|
||||
|
||||
|
||||
# Route inverter output to NAND
|
||||
end = vector(Abar_int_out.cx(), Abar_in.cy() + 0.5 * self.interconnect_width)
|
||||
self.add_segment_center(self.inv_layer, Abar_int_out.center(), end)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import math
|
|||
from .bitcell_base_array import bitcell_base_array
|
||||
from openram.base import vector
|
||||
from openram import OPTS
|
||||
from openram.sram_factory import factory
|
||||
from openram.sram_factory import factory
|
||||
from openram.tech import drc, layer
|
||||
|
||||
class rom_base_array(bitcell_base_array):
|
||||
|
|
@ -24,13 +24,13 @@ class rom_base_array(bitcell_base_array):
|
|||
self.tap_direction = tap_direction
|
||||
self.pitch_match = pitch_match
|
||||
self.bitline_layer = bitline_layer
|
||||
self.strap_spacing = strap_spacing
|
||||
self.strap_spacing = strap_spacing
|
||||
self.wordline_layer = wordline_layer
|
||||
self.data_col_size = self.column_size
|
||||
self.tap_spacing = tap_spacing
|
||||
|
||||
if strap_spacing != 0:
|
||||
self.array_col_size = self.column_size + math.ceil(self.column_size / strap_spacing)
|
||||
self.array_col_size = self.column_size + math.ceil(self.column_size / strap_spacing)
|
||||
else:
|
||||
self.array_col_size = self.column_size
|
||||
self.create_all_bitline_names()
|
||||
|
|
@ -41,7 +41,7 @@ class rom_base_array(bitcell_base_array):
|
|||
def create_netlist(self):
|
||||
self.add_modules()
|
||||
self.add_pins()
|
||||
|
||||
|
||||
self.create_cell_instances()
|
||||
self.create_precharge_inst()
|
||||
|
||||
|
|
@ -68,28 +68,28 @@ class rom_base_array(bitcell_base_array):
|
|||
ur = vector(ur.x, ur.y - self.m1_width)
|
||||
super().add_boundary(vector(0, 0), ur)
|
||||
self.width = ur.x
|
||||
self.height = ur.y
|
||||
|
||||
self.height = ur.y
|
||||
|
||||
def add_modules(self):
|
||||
|
||||
self.zero_cell = factory.create(module_name="rom_base_zero_cell",
|
||||
module_type="rom_base_cell",
|
||||
bitline_layer=self.bitline_layer,
|
||||
self.zero_cell = factory.create(module_name="rom_base_zero_cell",
|
||||
module_type="rom_base_cell",
|
||||
bitline_layer=self.bitline_layer,
|
||||
bit_value=0)
|
||||
|
||||
self.one_cell = factory.create(module_name="rom_base_one_cell",
|
||||
module_type="rom_base_cell",
|
||||
bitline_layer=self.bitline_layer,
|
||||
self.one_cell = factory.create(module_name="rom_base_one_cell",
|
||||
module_type="rom_base_cell",
|
||||
bitline_layer=self.bitline_layer,
|
||||
bit_value=1)
|
||||
|
||||
if self.tap_direction == "row":
|
||||
self.poly_tap = factory.create(module_type="rom_poly_tap")
|
||||
else:
|
||||
self.poly_tap = factory.create(module_type="rom_poly_tap")
|
||||
else:
|
||||
self.poly_tap = factory.create(module_type="rom_poly_tap", add_tap=True)
|
||||
self.precharge_array = factory.create(module_type="rom_precharge_array",
|
||||
cols=self.column_size,
|
||||
strap_spacing=self.strap_spacing,
|
||||
route_layer=self.bitline_layer,
|
||||
self.precharge_array = factory.create(module_type="rom_precharge_array",
|
||||
cols=self.column_size,
|
||||
strap_spacing=self.strap_spacing,
|
||||
route_layer=self.bitline_layer,
|
||||
strap_layer=self.wordline_layer,
|
||||
tap_direction=self.tap_direction)
|
||||
|
||||
|
|
@ -112,7 +112,8 @@ class rom_base_array(bitcell_base_array):
|
|||
self.cell_inst = {}
|
||||
self.cell_list = []
|
||||
self.current_row = 0
|
||||
#list of current bitline interconnect nets, starts as the same as the bitline list and is updated when new insts of cells are added
|
||||
# list of current bitline interconnect nets,
|
||||
# starts as the same as the bitline list and is updated when new insts of cells are added
|
||||
self.int_bl_list = self.bitline_names[0].copy()
|
||||
#When rotated correctly rows are word lines
|
||||
for row in range(self.row_size + 1):
|
||||
|
|
@ -126,7 +127,7 @@ class rom_base_array(bitcell_base_array):
|
|||
self.create_poly_tap(row, col)
|
||||
|
||||
new_inst = self.create_cell(row, col)
|
||||
|
||||
|
||||
self.cell_inst[row, col] = new_inst
|
||||
|
||||
row_list.append(new_inst)
|
||||
|
|
@ -151,7 +152,7 @@ class rom_base_array(bitcell_base_array):
|
|||
|
||||
# when col = 0, bl_h is connected to precharge, otherwise connect to previous bl connection
|
||||
# when col = col_size - 1 connected column_sizeto gnd otherwise create new bl connection
|
||||
if row == self.row_size :
|
||||
if row == self.row_size:
|
||||
|
||||
bl_l = self.int_bl_list[col]
|
||||
bl_h = "gnd"
|
||||
|
|
@ -168,16 +169,16 @@ class rom_base_array(bitcell_base_array):
|
|||
self.connect_inst([bl_h, bl_l, "precharge", "gnd"])
|
||||
elif self.data[row][col] == 1:
|
||||
new_inst = self.add_inst(name=name, mod=self.one_cell)
|
||||
self.connect_inst([bl_h, bl_l, self.wordline_names[0][row], "gnd"])
|
||||
else:
|
||||
self.connect_inst([bl_h, bl_l, self.wordline_names[0][row], "gnd"])
|
||||
else:
|
||||
new_inst = self.add_inst(name=name, mod=self.zero_cell)
|
||||
self.connect_inst([bl_h, self.wordline_names[0][row], "gnd"])
|
||||
|
||||
return new_inst
|
||||
return new_inst
|
||||
|
||||
def create_precharge_inst(self):
|
||||
prechrg_pins = self.bitline_names[0].copy()
|
||||
|
||||
|
||||
prechrg_pins.append("precharge")
|
||||
prechrg_pins.append("vdd")
|
||||
self.precharge_inst = self.add_inst(name="bitcell_array_precharge", mod=self.precharge_array)
|
||||
|
|
@ -215,14 +216,14 @@ class rom_base_array(bitcell_base_array):
|
|||
cell_y = row * (self.zero_cell.height) + pitch_offset
|
||||
|
||||
cell_x = 0
|
||||
for col in range(self.column_size):
|
||||
for col in range(self.column_size):
|
||||
|
||||
if col % self.strap_spacing == 0:
|
||||
self.strap_pos[row, col] = vector(cell_x, cell_y)
|
||||
self.tap_inst[row, col].place(self.strap_pos[row, col])
|
||||
|
||||
if self.tap_direction == "col":
|
||||
cell_x += self.poly_tap.pitch_offset
|
||||
cell_x += self.poly_tap.pitch_offset
|
||||
|
||||
self.cell_pos[row, col] = vector(cell_x, cell_y)
|
||||
self.cell_inst[row, col].place(self.cell_pos[row, col])
|
||||
|
|
@ -247,7 +248,7 @@ class rom_base_array(bitcell_base_array):
|
|||
end = drain.center()
|
||||
self.add_segment_center(self.bitline_layer, start, end)
|
||||
self.place_well_tap(row, col)
|
||||
|
||||
|
||||
def place_well_tap(self, row, col):
|
||||
cell = self.cell_inst[row, col]
|
||||
source = cell.get_pin("S")
|
||||
|
|
@ -271,7 +272,7 @@ class rom_base_array(bitcell_base_array):
|
|||
directions="nonpref")
|
||||
self.add_via_stack_center(offset=tap_pos,
|
||||
from_layer=self.active_stack[2],
|
||||
to_layer=self.wordline_layer)
|
||||
to_layer=self.wordline_layer)
|
||||
self.add_layout_pin_rect_center("gnd", self.wordline_layer, tap_pos)
|
||||
|
||||
def place_precharge(self):
|
||||
|
|
@ -279,7 +280,7 @@ class rom_base_array(bitcell_base_array):
|
|||
self.precharge_inst.place(offset=self.precharge_offset)
|
||||
self.copy_layout_pin(self.precharge_inst, "vdd")
|
||||
self.copy_layout_pin(self.precharge_inst, "gate", "precharge")
|
||||
|
||||
|
||||
def place_wordline_contacts(self):
|
||||
|
||||
for wl in range(self.row_size):
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ class rom_base_bank(design):
|
|||
self.num_inputs = ceil(log(self.rows, 2))
|
||||
self.col_bits = ceil(log(self.words_per_row, 2))
|
||||
self.row_bits = self.num_inputs
|
||||
|
||||
|
||||
# self.data = [[0, 1, 0, 1], [1, 1, 1, 1], [1, 1, 0, 0], [0, 0, 1, 0]]
|
||||
self.strap_spacing = strap_spacing
|
||||
self.tap_spacing = 8
|
||||
|
|
@ -38,7 +38,7 @@ class rom_base_bank(design):
|
|||
self.bitline_layer = "m1"
|
||||
self.wordline_layer = "m2"
|
||||
|
||||
|
||||
|
||||
if "li" in layer:
|
||||
self.route_stack = self.m1_stack
|
||||
else:
|
||||
|
|
@ -52,7 +52,7 @@ class rom_base_bank(design):
|
|||
Reads a hexadecimal file from a given directory to be used as the data written to the ROM
|
||||
endian is either "big" or "little"
|
||||
word_size is the number of bytes per word
|
||||
sets the row and column size based on the size of binary input, tries to keep array as square as possible,
|
||||
sets the row and column size based on the size of binary input, tries to keep array as square as possible,
|
||||
"""
|
||||
|
||||
def read_binary(self, data_file, word_size=2, endian="big", scramble_bits=False):
|
||||
|
|
@ -70,7 +70,7 @@ class rom_base_bank(design):
|
|||
bin_data = [int(x) for x in bin_data]
|
||||
|
||||
# data size in bytes
|
||||
data_size = len(bin_data) / 8
|
||||
data_size = len(bin_data) / 8
|
||||
num_words = int(data_size / word_size)
|
||||
|
||||
bytes_per_col = sqrt(num_words)
|
||||
|
|
@ -88,11 +88,11 @@ class rom_base_bank(design):
|
|||
if len(row_data) < bits_per_row:
|
||||
row_data = [0] * (bits_per_row - len(row_data)) + row_data
|
||||
chunked_data.append(row_data)
|
||||
|
||||
|
||||
|
||||
|
||||
# if endian == "big":
|
||||
|
||||
|
||||
|
||||
|
||||
self.data = chunked_data
|
||||
if scramble_bits:
|
||||
scrambled_chunked = []
|
||||
|
|
@ -104,9 +104,9 @@ class rom_base_bank(design):
|
|||
scambled_data.append(row_data[bit + word * self.word_size])
|
||||
scrambled_chunked.append(scambled_data)
|
||||
self.data = scrambled_chunked
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# self.data.reverse()
|
||||
|
||||
debug.info(1, "Read rom binary: length {0} bytes, {1} words, set number of cols to {2}, rows to {3}, with {4} words per row".format(data_size, num_words, self.cols, self.rows, self.words_per_row))
|
||||
|
|
@ -117,7 +117,7 @@ class rom_base_bank(design):
|
|||
self.add_pins()
|
||||
|
||||
|
||||
|
||||
|
||||
def create_layout(self):
|
||||
self.create_instances()
|
||||
self.place_instances()
|
||||
|
|
@ -144,7 +144,7 @@ class rom_base_bank(design):
|
|||
self.interconnect_layer_pitch = drc["{0}_to_{0}".format(self.interconnect_layer)]
|
||||
|
||||
def add_pins(self):
|
||||
|
||||
|
||||
self.add_pin("clk", "INPUT")
|
||||
self.add_pin("CS", "INPUT")
|
||||
|
||||
|
|
@ -163,59 +163,59 @@ class rom_base_bank(design):
|
|||
def add_modules(self):
|
||||
|
||||
# TODO: provide technology-specific calculation of these parameters
|
||||
# in sky130 the address control buffer is composed of 2 size 2 NAND gates,
|
||||
# in sky130 the address control buffer is composed of 2 size 2 NAND gates,
|
||||
# with a beta of 3, each of these gates has gate capacitance of 2 min sized inverters, therefor a load of 4
|
||||
addr_control_buffer_effort = 4
|
||||
# a single min sized nmos makes up 1/4 of the input capacitance of a min sized inverter
|
||||
bitcell_effort = 0.25
|
||||
|
||||
# Takes into account inverter sizing
|
||||
# Takes into account inverter sizing
|
||||
wordline_effort = bitcell_effort * 0.5
|
||||
|
||||
# a single min sized pmos plus a single min sized nmos have approximately half the gate capacitance of a min inverter
|
||||
# an additional 0.2 accounts for the long wire capacitance and add delay to gaurentee the read timing
|
||||
precharge_cell_effort = 0.5 + 0.2
|
||||
|
||||
self.array = factory.create(module_type="rom_base_array",
|
||||
cols=self.cols,
|
||||
rows=self.rows,
|
||||
strap_spacing=self.strap_spacing,
|
||||
bitmap=self.data,
|
||||
self.array = factory.create(module_type="rom_base_array",
|
||||
cols=self.cols,
|
||||
rows=self.rows,
|
||||
strap_spacing=self.strap_spacing,
|
||||
bitmap=self.data,
|
||||
bitline_layer=self.bitline_layer,
|
||||
wordline_layer=self.wordline_layer,
|
||||
pitch_match=True,
|
||||
tap_spacing=self.tap_spacing)
|
||||
|
||||
|
||||
self.decode_array = factory.create(module_name="rom_row_decode",
|
||||
module_type="rom_decoder",
|
||||
num_outputs=self.rows,
|
||||
strap_spacing=self.strap_spacing,
|
||||
route_layer=self.route_layer,
|
||||
tap_spacing=self.tap_spacing)
|
||||
|
||||
|
||||
self.decode_array = factory.create(module_name="rom_row_decode",
|
||||
module_type="rom_decoder",
|
||||
num_outputs=self.rows,
|
||||
strap_spacing=self.strap_spacing,
|
||||
route_layer=self.route_layer,
|
||||
fanout=(self.cols)*wordline_effort )
|
||||
|
||||
|
||||
self.column_mux = factory.create(module_type="rom_column_mux_array",
|
||||
|
||||
self.column_mux = factory.create(module_type="rom_column_mux_array",
|
||||
columns=self.cols,
|
||||
word_size=self.word_size,
|
||||
tap_spacing=self.strap_spacing,
|
||||
bitline_layer=self.interconnect_layer,
|
||||
input_layer=self.bitline_layer)
|
||||
|
||||
|
||||
self.column_decode = factory.create(module_name="rom_column_decode",
|
||||
module_type="rom_decoder",
|
||||
num_outputs=self.words_per_row,
|
||||
strap_spacing=self.strap_spacing,
|
||||
route_layer=self.route_layer,
|
||||
module_type="rom_decoder",
|
||||
num_outputs=self.words_per_row,
|
||||
strap_spacing=self.strap_spacing,
|
||||
route_layer=self.route_layer,
|
||||
fanout=2,
|
||||
invert_outputs=True )
|
||||
|
||||
self.control_logic = factory.create(module_type="rom_control_logic",
|
||||
self.control_logic = factory.create(module_type="rom_control_logic",
|
||||
num_outputs=(self.cols + self.words_per_row * precharge_cell_effort) \
|
||||
+ (addr_control_buffer_effort * self.col_bits),
|
||||
+ (addr_control_buffer_effort * self.col_bits),
|
||||
clk_fanout=(self.row_bits * addr_control_buffer_effort) + (precharge_cell_effort * self.rows),
|
||||
height=self.column_decode.height )
|
||||
|
||||
|
||||
self.bitline_inv = factory.create(module_type="rom_wordline_driver_array",
|
||||
module_name="rom_bitline_inverter",
|
||||
rows=self.cols,
|
||||
|
|
@ -247,7 +247,7 @@ class rom_base_bank(design):
|
|||
bitline_bar = ["bl_b_{}".format(bl) for bl in range(self.cols)]
|
||||
pre_buf_outputs = ["rom_out_prebuf_{}".format(bit) for bit in range(self.word_size)]
|
||||
outputs = ["rom_out_{}".format(bl) for bl in range(self.word_size)]
|
||||
|
||||
|
||||
|
||||
array_pins = bitlines + wordlines + prechrg + vdd + gnd
|
||||
|
||||
|
|
@ -283,7 +283,7 @@ class rom_base_bank(design):
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
def place_instances(self):
|
||||
self.place_row_decoder()
|
||||
self.place_data_array()
|
||||
|
|
@ -297,10 +297,10 @@ class rom_base_bank(design):
|
|||
def place_row_decoder(self):
|
||||
self.decode_offset = vector(0, self.control_inst.height )
|
||||
self.decode_inst.place(offset=self.decode_offset)
|
||||
|
||||
|
||||
def place_data_array(self):
|
||||
# We approximate the correct position for the array
|
||||
array_x = self.decode_inst.width + (2) * ( self.route_layer_width + self.route_layer_pitch )
|
||||
array_x = self.decode_inst.width + (2) * ( self.route_layer_width + self.route_layer_pitch )
|
||||
array_y = self.decode_array.buf_inst.height - self.array.precharge_inst.cy() - self.array.zero_cell.height * 0.5
|
||||
self.array_offset = vector(array_x ,array_y)
|
||||
self.array_inst.place(offset=self.array_offset)
|
||||
|
|
@ -308,7 +308,7 @@ class rom_base_bank(design):
|
|||
# now move array to correct alignment with decoder
|
||||
array_align = self.decode_inst.get_pin("wl_0").cy() - self.array_inst.get_pin("wl_0_0").cy()
|
||||
self.array_inst.place(offset=(self.array_offset + vector(0, array_align)))
|
||||
|
||||
|
||||
def place_bitline_inverter(self):
|
||||
self.bitline_inv_inst.place(offset=[0,0], rotate=90)
|
||||
inv_y_offset = self.array_inst.by() - self.bitline_inv_inst.width - 2 * self.m1_pitch
|
||||
|
|
@ -316,14 +316,14 @@ class rom_base_bank(design):
|
|||
inv_x_offset = self.array_inst.get_pin("bl_0_0").cx() - self.bitline_inv_inst.get_pin("out_0").cx()
|
||||
self.inv_offset = vector(inv_x_offset, inv_y_offset)
|
||||
self.bitline_inv_inst.place(offset=self.inv_offset, rotate=90)
|
||||
|
||||
|
||||
def place_control_logic(self):
|
||||
|
||||
self.control_offset = vector(self.col_decode_inst.lx() - self.control_inst.width - 3 * self.m1_pitch, self.decode_inst.by() - self.control_logic.height - self.m1_pitch)
|
||||
self.control_inst.place(offset=self.control_offset)
|
||||
|
||||
def place_col_decoder(self):
|
||||
col_decode_y = self.mux_inst.get_pin("sel_0").cy() - self.col_decode_inst.get_pin("wl_0").cy()
|
||||
col_decode_y = self.mux_inst.get_pin("sel_0").cy() - self.col_decode_inst.get_pin("wl_0").cy()
|
||||
self.col_decode_offset = vector(self.decode_inst.width - self.col_decode_inst.width, col_decode_y)
|
||||
self.col_decode_inst.place(offset=self.col_decode_offset)
|
||||
|
||||
|
|
@ -333,13 +333,13 @@ class rom_base_bank(design):
|
|||
mux_x_offset = self.bitline_inv_inst.get_pin("out_0").cx() - self.mux_inst.get_pin("bl_0").cx()
|
||||
self.mux_offset = vector(mux_x_offset, mux_y_offset)
|
||||
self.mux_inst.place(offset=self.mux_offset)
|
||||
|
||||
|
||||
def place_output_buffer(self):
|
||||
output_x = self.col_decode_inst.rx() + self.output_inv_inst.height
|
||||
output_x = self.col_decode_inst.rx() + self.output_inv_inst.height
|
||||
output_y = self.mux_inst.by() - self.word_size * self.m1_pitch
|
||||
self.output_inv_offset = vector(output_x, output_y)
|
||||
self.output_inv_inst.place(offset=self.output_inv_offset, rotate=270)
|
||||
|
||||
|
||||
def route_decode_outputs(self):
|
||||
# for the row decoder
|
||||
route_pins = [self.array_inst.get_pin("wl_0_{}".format(wl)) for wl in range(self.rows)]
|
||||
|
|
@ -369,11 +369,11 @@ class rom_base_bank(design):
|
|||
|
||||
self.add_segment_center(self.interconnect_layer, start, end)
|
||||
|
||||
|
||||
|
||||
def route_precharge(self):
|
||||
|
||||
prechrg_control = self.control_inst.get_pin("prechrg")
|
||||
|
||||
|
||||
col_decode_prechrg = self.col_decode_inst.get_pin("precharge_r")
|
||||
col_decode_clk = self.col_decode_inst.get_pin("clk")
|
||||
array_prechrg = self.array_inst.get_pin("precharge")
|
||||
|
|
@ -401,19 +401,19 @@ class rom_base_bank(design):
|
|||
self.add_via_stack_center(from_layer=self.route_stack[0],
|
||||
to_layer=col_decode_prechrg.layer,
|
||||
offset=end)
|
||||
|
||||
|
||||
start = mid1
|
||||
mid1 = vector(self.control_inst.rx(), start.y)
|
||||
mid2 = vector(mid1.x, col_decode_clk.cy())
|
||||
end = col_decode_clk.center()
|
||||
self.add_path(self.route_stack[0], [start, mid1, mid2, end])
|
||||
|
||||
# self.add_segment_center(col_decode_prechrg.layer, end, col_decode_prechrg.center())
|
||||
# self.add_segment_center(col_decode_prechrg.layer, end, col_decode_prechrg.center())
|
||||
|
||||
# Route precharge to main array
|
||||
# end = vector(col_decode_prechrg.cx(), array_prechrg.cy())
|
||||
mid = vector(col_decode_prechrg.cx(), array_prechrg.cy() )
|
||||
self.add_path(self.route_stack[0], [array_prechrg.center(), mid, col_decode_prechrg.center()])
|
||||
self.add_path(self.route_stack[0], [array_prechrg.center(), mid, col_decode_prechrg.center()])
|
||||
|
||||
|
||||
def route_clock(self):
|
||||
|
|
@ -423,8 +423,8 @@ class rom_base_bank(design):
|
|||
self.add_via_stack_center(from_layer=self.route_stack[2],
|
||||
to_layer=clk_out.layer,
|
||||
offset=clk_out.center())
|
||||
|
||||
# Route clock to row decoder
|
||||
|
||||
# Route clock to row decoder
|
||||
mid = vector(self.control_inst.rx() + self.m1_pitch, clk_out.cy())
|
||||
|
||||
addr_control_clk = row_decode_clk.rc() + vector( 2 * self.route_layer_pitch + self.route_layer_width, 0)
|
||||
|
|
@ -474,7 +474,7 @@ class rom_base_bank(design):
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
def place_top_level_pins(self):
|
||||
self.copy_layout_pin(self.control_inst, "CS")
|
||||
self.copy_layout_pin(self.control_inst, "clk_in", "clk")
|
||||
|
|
@ -487,10 +487,10 @@ class rom_base_bank(design):
|
|||
|
||||
for msb in range(self.col_bits, self.row_bits + self.col_bits):
|
||||
name = "addr_{}".format(msb)
|
||||
pin_num = msb - self.col_bits
|
||||
pin_num = msb - self.col_bits
|
||||
self.copy_layout_pin(self.decode_inst, "A{}".format(pin_num), name)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def route_supplies(self):
|
||||
|
|
|
|||
|
|
@ -23,15 +23,15 @@ class rom_base_cell(design):
|
|||
self.create_netlist()
|
||||
self.create_layout()
|
||||
|
||||
|
||||
|
||||
def create_netlist(self):
|
||||
|
||||
def create_netlist(self):
|
||||
self.add_pins()
|
||||
self.add_modules()
|
||||
|
||||
|
||||
|
||||
|
||||
def create_layout(self):
|
||||
|
||||
|
||||
self.create_tx()
|
||||
self.setup_drc_offsets()
|
||||
self.add_boundary()
|
||||
|
|
@ -41,22 +41,22 @@ class rom_base_cell(design):
|
|||
if self.bit_value == 0:
|
||||
self.short_gate()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Calculates offsets of cell width and height so that tiling of cells does not violate any drc rules
|
||||
def setup_drc_offsets(self):
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
self.poly_size = (self.cell_inst.width + self.active_space) - (self.cell_inst.height + 2 * self.poly_extend_active)
|
||||
#nmos contact to gate distance
|
||||
self.contact_to_gate = 0.5 * (self.nmos.width - 2 * self.nmos.contact_width - self.nmos.poly_width - 2 * self.active_enclose_contact)
|
||||
self.contact_to_gate = 0.5 * (self.nmos.width - 2 * self.nmos.contact_width - self.nmos.poly_width - 2 * self.active_enclose_contact)
|
||||
|
||||
#height offset to account for active-to-active spacing between adjacent bitlines
|
||||
self.poly_extend_active_spacing = abs( 2 * self.nmos.poly_extend_active - drc("active_to_active") )
|
||||
|
||||
#contact to contact distance, minimum cell width before drc offsets
|
||||
#contact to contact distance, minimum cell width before drc offsets
|
||||
self.base_width = self.nmos.width - 2 * self.active_enclose_contact - self.nmos.contact_width
|
||||
|
||||
#width offset to account for active-to-active spacing between cells on the same bitline
|
||||
|
|
@ -66,19 +66,19 @@ class rom_base_cell(design):
|
|||
# width offset to account for poly-active spacing between base and dummy cells on the same bitline
|
||||
self.poly_active_offset = 0.5 * (self.base_width - 2 * self.cell_diffusion_offset - (self.poly_width + 2 * self.active_enclose_contact + self.nmos.contact_width)) - self.poly_to_active
|
||||
|
||||
#so that the poly taps are far enough apart
|
||||
#so that the poly taps are far enough apart
|
||||
self.poly_tap_offset = (self.base_width - self.cell_diffusion_offset - self.poly_contact.width - self.poly_active_offset) - drc("poly_to_poly")
|
||||
|
||||
|
||||
|
||||
def add_boundary(self):
|
||||
|
||||
height = self.cell_inst.width + self.active_space
|
||||
|
||||
#cell width with offsets applied, height becomes width when the cells are rotated
|
||||
#cell width with offsets applied, height becomes width when the cells are rotated
|
||||
width = self.cell_inst.height + 2 * self.poly_extend_active
|
||||
# cell height with offsets applied, width becomes height when the cells are rotated, if the offsets are positive (greater than 0) they are not applied
|
||||
# height = self.base_width - min(self.cell_diffusion_offset, 0) - min(self.poly_active_offset, 0) - min(self.poly_tap_offset, 0)
|
||||
|
||||
|
||||
# make the cells square so the pitch of wordlines will match bitlines
|
||||
|
||||
if width > height:
|
||||
|
|
@ -87,10 +87,10 @@ class rom_base_cell(design):
|
|||
else:
|
||||
self.width = height
|
||||
self.height = height
|
||||
|
||||
|
||||
super().add_boundary()
|
||||
|
||||
|
||||
|
||||
def add_modules(self):
|
||||
|
||||
self.nmos = factory.create(module_type="ptx",
|
||||
|
|
@ -103,14 +103,14 @@ class rom_base_cell(design):
|
|||
|
||||
def create_tx(self):
|
||||
self.cell_inst = self.add_inst( name=self.name + "_nmos",
|
||||
mod=self.nmos,
|
||||
mod=self.nmos,
|
||||
)
|
||||
if self.bit_value == 0:
|
||||
self.connect_inst(["bl", "wl", "bl", "gnd"])
|
||||
else:
|
||||
self.connect_inst(["bl_h", "wl", "bl_l", "gnd"])
|
||||
|
||||
|
||||
|
||||
def add_pins(self):
|
||||
if self.bit_value == 0 :
|
||||
pin_list = ["bl", "wl", "gnd"]
|
||||
|
|
@ -119,7 +119,7 @@ class rom_base_cell(design):
|
|||
pin_list = ["bl_h", "bl_l", "wl", "gnd"]
|
||||
dir_list = ["INOUT", "INOUT", "INPUT", "GROUND"]
|
||||
|
||||
self.add_pin_list(pin_list, dir_list)
|
||||
self.add_pin_list(pin_list, dir_list)
|
||||
|
||||
def place_tx(self):
|
||||
|
||||
|
|
@ -127,7 +127,7 @@ class rom_base_cell(design):
|
|||
tx_offset = vector(self.poly_extend_active + self.cell_inst.height + self.poly_size,- 0.5 * self.contact_width - self.active_enclose_contact)
|
||||
# add rect of poly to account for offset from drc spacing
|
||||
# self.add_rect_center("poly", poly_offset, self.poly_extend_active_spacing, self.poly_width)
|
||||
|
||||
|
||||
self.cell_inst.place(tx_offset, rotate=90)
|
||||
# self.add_label("CELL ZERO", self.route_layer)
|
||||
self.copy_layout_pin(self.cell_inst, "S", "S")
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ class rom_column_mux(pgate):
|
|||
|
||||
def create_layout(self):
|
||||
|
||||
|
||||
|
||||
self.pin_layer = self.input_layer
|
||||
self.pin_pitch = getattr(self, "{}_pitch".format(self.pin_layer))
|
||||
self.pin_width = getattr(self, "{}_width".format(self.pin_layer))
|
||||
|
|
|
|||
|
|
@ -54,14 +54,14 @@ class rom_column_mux_array(design):
|
|||
self.setup_layout_constants()
|
||||
self.place_array()
|
||||
self.add_routing()
|
||||
|
||||
|
||||
# Find the highest shapes to determine height before adding well
|
||||
highest = self.find_highest_coords()
|
||||
self.height = highest.y
|
||||
self.add_layout_pins()
|
||||
if "pwell" in layer:
|
||||
self.add_enclosure(self.mux_inst, "pwell")
|
||||
|
||||
|
||||
self.add_boundary()
|
||||
self.DRC_LVS()
|
||||
|
||||
|
|
@ -154,7 +154,7 @@ class rom_column_mux_array(design):
|
|||
def add_vertical_poly_rail(self):
|
||||
""" Connect the poly to the address rails """
|
||||
|
||||
|
||||
|
||||
# Offset to the first transistor gate in the pass gate
|
||||
for col in range(self.columns):
|
||||
# which select bit should this column connect to depends on the position in the word
|
||||
|
|
@ -209,8 +209,8 @@ class rom_column_mux_array(design):
|
|||
|
||||
def add_taps(self):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
|
||||
def graph_exclude_columns(self, column_include_num):
|
||||
"""
|
||||
Excludes all columns muxes unrelated to the target bit being simulated.
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class rom_control_logic(design):
|
|||
self.gate_height = 20 * self.m1_pitch
|
||||
self.driver_height = self.gate_height
|
||||
|
||||
|
||||
|
||||
self.clk_fanout = clk_fanout
|
||||
|
||||
if "li" in layer:
|
||||
|
|
@ -49,21 +49,21 @@ class rom_control_logic(design):
|
|||
self.route_insts()
|
||||
|
||||
def add_modules(self):
|
||||
self.buf_mod = factory.create(module_type="pdriver",
|
||||
module_name="rom_clock_driver",
|
||||
self.buf_mod = factory.create(module_type="pdriver",
|
||||
module_name="rom_clock_driver",
|
||||
height=self.gate_height,
|
||||
fanout=self.clk_fanout + 2,
|
||||
add_wells=True,
|
||||
)
|
||||
self.nand_mod = factory.create(module_type="pnand2",
|
||||
module_name="rom_control_nand",
|
||||
height=self.gate_height,
|
||||
self.nand_mod = factory.create(module_type="pnand2",
|
||||
module_name="rom_control_nand",
|
||||
height=self.gate_height,
|
||||
add_wells=False)
|
||||
self.driver_mod = factory.create(module_type="pdriver",
|
||||
module_name="rom_precharge_driver",
|
||||
inverting=True,
|
||||
fanout=self.output_size,
|
||||
height=self.driver_height,
|
||||
self.driver_mod = factory.create(module_type="pdriver",
|
||||
module_name="rom_precharge_driver",
|
||||
inverting=True,
|
||||
fanout=self.output_size,
|
||||
height=self.driver_height,
|
||||
add_wells=True)
|
||||
|
||||
def add_pins(self):
|
||||
|
|
@ -75,7 +75,7 @@ class rom_control_logic(design):
|
|||
self.add_pin("gnd", "GROUND")
|
||||
|
||||
def create_instances(self):
|
||||
|
||||
|
||||
self.buf_inst = self.add_inst(name="clk_driver", mod=self.buf_mod)
|
||||
self.connect_inst(["clk_in", "clk_out", "vdd", "gnd"])
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ class rom_decoder(design):
|
|||
self.num_outputs = num_outputs
|
||||
self.num_inputs = ceil(log(num_outputs, 2))
|
||||
self.create_decode_map()
|
||||
|
||||
|
||||
super().__init__(name)
|
||||
|
||||
b = factory.create(module_type=OPTS.bitcell)
|
||||
|
|
@ -48,7 +48,7 @@ class rom_decoder(design):
|
|||
self.place_input_buffer()
|
||||
self.place_driver()
|
||||
self.route_outputs()
|
||||
|
||||
|
||||
self.connect_inputs()
|
||||
self.route_supplies()
|
||||
self.add_boundary()
|
||||
|
|
@ -62,7 +62,7 @@ class rom_decoder(design):
|
|||
ur = vector(ur.x, ur.y)
|
||||
super().add_boundary(ll, ur)
|
||||
self.width = ur.x
|
||||
self.height = ur.y
|
||||
self.height = ur.y
|
||||
|
||||
def setup_layout_constants(self):
|
||||
self.inv_route_width = drc["minwidth_{}".format(self.inv_route_layer)]
|
||||
|
|
@ -87,7 +87,7 @@ class rom_decoder(design):
|
|||
else:
|
||||
bin_digit = int(addr[addr_idx])
|
||||
|
||||
col_array.append(bin_digit)
|
||||
col_array.append(bin_digit)
|
||||
|
||||
if bin_digit == 0 : inv_col_array.append(1)
|
||||
else : inv_col_array.append(0)
|
||||
|
|
@ -109,19 +109,19 @@ class rom_decoder(design):
|
|||
|
||||
def add_modules(self):
|
||||
|
||||
self.control_array = factory.create(module_type="rom_address_control_array",
|
||||
self.control_array = factory.create(module_type="rom_address_control_array",
|
||||
cols=self.num_inputs)
|
||||
|
||||
self.wordline_buf = factory.create(module_type="rom_wordline_driver_array", module_name="{}_wordline_buffer".format(self.name),
|
||||
rows=self.num_outputs,
|
||||
self.wordline_buf = factory.create(module_type="rom_wordline_driver_array", module_name="{}_wordline_buffer".format(self.name),
|
||||
rows=self.num_outputs,
|
||||
fanout=ceil(self.fanout),
|
||||
invert_outputs=self.invert_outputs,
|
||||
tap_spacing=self.strap_spacing)
|
||||
|
||||
self.array_mod = factory.create(module_type="rom_base_array",
|
||||
module_name="{}_array".format(self.name),
|
||||
cols=self.num_outputs,
|
||||
rows=2 * self.num_inputs,
|
||||
|
||||
self.array_mod = factory.create(module_type="rom_base_array",
|
||||
module_name="{}_array".format(self.name),
|
||||
cols=self.num_outputs,
|
||||
rows=2 * self.num_inputs,
|
||||
bitmap=self.decode_map,
|
||||
strap_spacing = self.strap_spacing,
|
||||
bitline_layer=self.output_layer,
|
||||
|
|
@ -190,7 +190,7 @@ class rom_decoder(design):
|
|||
self.array_inst.place(offset, rotate=90)
|
||||
|
||||
def place_driver(self):
|
||||
|
||||
|
||||
offset = vector(self.array_inst.height + self.m1_width, self.array_inst.by())
|
||||
self.wordline_buf_inst.place(offset)
|
||||
|
||||
|
|
@ -226,7 +226,7 @@ class rom_decoder(design):
|
|||
addr_bar_out_pin = self.buf_inst.get_pin("Abar{}_out".format(i))
|
||||
|
||||
addr_middle = vector(addr_pin.cx(), addr_out_pin.cy())
|
||||
|
||||
|
||||
addr_bar_middle = vector(addr_bar_pin.cx(), addr_bar_out_pin.cy())
|
||||
|
||||
self.add_path(self.inv_route_layer, [addr_out_pin.center(), addr_middle, addr_pin.center()])
|
||||
|
|
|
|||
|
|
@ -37,11 +37,11 @@ class rom_poly_tap(design):
|
|||
self.extend_poly()
|
||||
|
||||
def add_boundary(self):
|
||||
contact_width = self.poly_contact.width
|
||||
contact_width = self.poly_contact.width
|
||||
|
||||
# offset = self.active_space - (contact_width - self.active_enclose_contact - self.active_extend_contact)
|
||||
self.height = self.dummy.height
|
||||
self.width = contact_width + self.pitch_offset
|
||||
self.width = contact_width + self.pitch_offset
|
||||
|
||||
super().add_boundary()
|
||||
|
||||
|
|
@ -89,7 +89,7 @@ class rom_poly_tap(design):
|
|||
offset = self.active_space - gap
|
||||
# tap_x = self.via.cx() + self.contact_width + self.active_enclose_contact + self.poly_enclose_contact
|
||||
tap_x = self.via.cx() + offset
|
||||
tap_y = self.via.cy() + self.dummy.width * 0.5
|
||||
tap_y = self.via.cy() + self.dummy.width * 0.5
|
||||
contact_pos = vector(tap_x, tap_y)
|
||||
|
||||
# edge of the next nmos
|
||||
|
|
@ -105,7 +105,7 @@ class rom_poly_tap(design):
|
|||
implant_type="p",
|
||||
well_type="p",
|
||||
directions="nonpref")
|
||||
self.add_power_pin(name="gnd",
|
||||
self.add_power_pin(name="gnd",
|
||||
loc=contact_pos,
|
||||
start_layer=self.active_stack[2])
|
||||
self.add_layout_pin_rect_center("active_tap", self.supply_stack[0], contact_pos)
|
||||
|
|
@ -32,14 +32,14 @@ class rom_precharge_array(design):
|
|||
name = "rom_inv_array_{0}".format(cols)
|
||||
|
||||
if strap_spacing != None:
|
||||
self.strap_spacing = strap_spacing
|
||||
self.strap_spacing = strap_spacing
|
||||
else:
|
||||
self.strap_spacing = 0
|
||||
|
||||
|
||||
if strap_spacing != 0:
|
||||
self.num_straps = ceil(self.cols / self.strap_spacing)
|
||||
self.array_col_size = self.cols + self.num_straps
|
||||
self.array_col_size = self.cols + self.num_straps
|
||||
else:
|
||||
self.num_straps = 0
|
||||
self.array_col_size = self.cols
|
||||
|
|
@ -54,7 +54,7 @@ class rom_precharge_array(design):
|
|||
self.create_instances()
|
||||
|
||||
def create_layout(self):
|
||||
self.width = self.cols * self.pmos.width
|
||||
self.width = self.cols * self.pmos.width
|
||||
self.height = self.pmos.width
|
||||
self.place_instances()
|
||||
self.create_layout_pins()
|
||||
|
|
@ -70,7 +70,7 @@ class rom_precharge_array(design):
|
|||
self.add_label(layer="nwell", text="upper right",offset=ur)
|
||||
# ur = vector(ur.x, ur.y - self.well_ll.y)
|
||||
super().add_boundary(vector(0, 0), ur)
|
||||
self.height = ur.y
|
||||
self.height = ur.y
|
||||
self.width = ur.x
|
||||
|
||||
def create_modules(self):
|
||||
|
|
@ -118,8 +118,8 @@ class rom_precharge_array(design):
|
|||
self.add_label("ZERO", self.route_layer)
|
||||
|
||||
self.array_pos = []
|
||||
strap_num = 0
|
||||
cell_y = 0
|
||||
strap_num = 0
|
||||
cell_y = 0
|
||||
# columns are bit lines
|
||||
cell_x = 0
|
||||
|
||||
|
|
@ -163,7 +163,7 @@ class rom_precharge_array(design):
|
|||
start = vector(tap_pin.cx(), tap_pin.by())
|
||||
end = vector(start.x, tap.mod.get_pin("poly_tap").cy())
|
||||
self.add_segment_center(layer="poly", start=start, end=end)
|
||||
offset_start = vector(end.x - self.poly_tap.width + self.poly_extend_active, end.y)
|
||||
offset_start = vector(end.x - self.poly_tap.width + self.poly_extend_active, end.y)
|
||||
offset_end = end + vector(0.5*self.poly_width, 0)
|
||||
self.add_segment_center(layer="poly", start=offset_start, end=offset_end)
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ class rom_precharge_cell(rom_base_cell):
|
|||
|
||||
def create_layout(self):
|
||||
super().create_layout()
|
||||
|
||||
|
||||
self.place_tap()
|
||||
self.extend_well()
|
||||
|
||||
|
|
@ -37,27 +37,27 @@ class rom_precharge_cell(rom_base_cell):
|
|||
|
||||
def create_tx(self):
|
||||
self.cell_inst = self.add_inst( name="precharge_pmos",
|
||||
mod=self.pmos,
|
||||
mod=self.pmos,
|
||||
)
|
||||
self.connect_inst(["bitline", "gate", "vdd", "vdd"])
|
||||
|
||||
def add_pins(self):
|
||||
def add_pins(self):
|
||||
pin_list = ["vdd", "gate", "bitline"]
|
||||
dir_list = ["POWER", "INPUT", "OUTPUT"]
|
||||
|
||||
self.add_pin_list(pin_list, dir_list)
|
||||
self.add_pin_list(pin_list, dir_list)
|
||||
|
||||
def setup_drc_offsets(self):
|
||||
|
||||
self.poly_size = (self.cell_inst.width + self.active_space) - (self.cell_inst.height + 2 * self.poly_extend_active)
|
||||
|
||||
#contact to contact distance, minimum cell width before drc offsets
|
||||
#contact to contact distance, minimum cell width before drc offsets
|
||||
self.base_width = self.pmos.width - 2 * self.active_enclose_contact - self.pmos.contact_width
|
||||
|
||||
# width offset to account for poly-active spacing between base and dummy cells on the same bitline
|
||||
self.poly_active_offset = 0.5 * (self.base_width - (self.poly_width + 2 * self.active_enclose_contact + self.pmos.contact_width)) - self.poly_to_active
|
||||
|
||||
#so that the poly taps are far enough apart
|
||||
#so that the poly taps are far enough apart
|
||||
self.poly_tap_offset = (self.base_width - self.poly_contact.width - self.poly_active_offset) - drc("poly_to_poly")
|
||||
|
||||
def extend_well(self):
|
||||
|
|
@ -82,7 +82,7 @@ class rom_precharge_cell(rom_base_cell):
|
|||
directions="nonpref")
|
||||
self.add_via_stack_center(offset=pos,
|
||||
from_layer=self.active_stack[2],
|
||||
to_layer=self.supply_layer)
|
||||
to_layer=self.supply_layer)
|
||||
|
||||
bitline_offset = vector( 2 * (drc("minwidth_{}".format(self.bitline_layer)) + drc("{0}_to_{0}".format(self.bitline_layer))) ,0)
|
||||
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ class rom_wordline_driver_array(design):
|
|||
height=b.height,
|
||||
add_wells=False,
|
||||
flip_io=self.flip_io)
|
||||
|
||||
|
||||
else:
|
||||
self.wl_driver = factory.create(module_type="pbuf_dec",
|
||||
size=self.fanout,
|
||||
|
|
@ -136,7 +136,7 @@ class rom_wordline_driver_array(design):
|
|||
# output each WL on the right
|
||||
if self.flip_io:
|
||||
wl_offset = out_pin.lc() - vector(1.6 * route_width, 0)
|
||||
|
||||
|
||||
else:
|
||||
wl_offset = out_pin.rc() - vector( 0.5 * route_width, 0)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env python3
|
||||
# See LICENSE for licensing information.
|
||||
#
|
||||
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||
# Copyright (c) 2016-2023 Regents of the University of California and The Board
|
||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||
# (acting for and on behalf of Oklahoma State University)
|
||||
# All rights reserved.
|
||||
|
|
|
|||
Loading…
Reference in New Issue