mirror of https://github.com/VLSIDA/OpenRAM.git
Optimizations to pbitcell spacings
This commit is contained in:
parent
98a00f985b
commit
dc96d86082
|
|
@ -39,6 +39,7 @@ class design(hierarchy_design):
|
||||||
self.m3_width = drc("minwidth_metal3")
|
self.m3_width = drc("minwidth_metal3")
|
||||||
self.m3_space = drc("metal3_to_metal3")
|
self.m3_space = drc("metal3_to_metal3")
|
||||||
self.active_width = drc("minwidth_active")
|
self.active_width = drc("minwidth_active")
|
||||||
|
self.active_space = drc("active_to_body_active")
|
||||||
self.contact_width = drc("minwidth_contact")
|
self.contact_width = drc("minwidth_contact")
|
||||||
|
|
||||||
self.poly_to_active = drc("poly_to_active")
|
self.poly_to_active = drc("poly_to_active")
|
||||||
|
|
|
||||||
|
|
@ -197,8 +197,10 @@ class pbitcell(design.design):
|
||||||
self.inverter_nmos_ypos = self.port_ypos
|
self.inverter_nmos_ypos = self.port_ypos
|
||||||
|
|
||||||
# spacing between ports
|
# spacing between ports
|
||||||
self.bitline_offset = -self.active_width + 0.5*contact.m1m2.height + self.m2_space + self.m2_width
|
self.bitline_offset = -0.5*self.readwrite_nmos.active_width + 0.5*contact.m1m2.height + self.m2_space + self.m2_width
|
||||||
self.port_spacing = self.bitline_offset + self.m2_space
|
m2_constraint = self.bitline_offset + self.m2_space + 0.5*contact.m1m2.height - 0.5*self.readwrite_nmos.active_width
|
||||||
|
self.rw_w_spacing = max(self.active_space, self.m1_space, m2_constraint)
|
||||||
|
self.r_spacing = self.bitline_offset + self.m2_space
|
||||||
|
|
||||||
# spacing between cross coupled inverters
|
# spacing between cross coupled inverters
|
||||||
self.inverter_to_inverter_spacing = contact.poly.height + self.m1_space
|
self.inverter_to_inverter_spacing = contact.poly.height + self.m1_space
|
||||||
|
|
@ -236,9 +238,9 @@ class pbitcell(design.design):
|
||||||
self.topmost_ypos = self.inverter_nmos_ypos + self.inverter_nmos.active_height + self.inverter_gap + self.inverter_pmos.active_height + self.vdd_offset
|
self.topmost_ypos = self.inverter_nmos_ypos + self.inverter_nmos.active_height + self.inverter_gap + self.inverter_pmos.active_height + self.vdd_offset
|
||||||
|
|
||||||
self.leftmost_xpos = -0.5*self.inverter_to_inverter_spacing - self.inverter_nmos.active_width \
|
self.leftmost_xpos = -0.5*self.inverter_to_inverter_spacing - self.inverter_nmos.active_width \
|
||||||
- self.num_rw_ports*(self.readwrite_nmos.active_width + self.port_spacing) \
|
- self.num_rw_ports*(self.readwrite_nmos.active_width + self.rw_w_spacing) \
|
||||||
- self.num_w_ports*(self.write_nmos.active_width + self.port_spacing) \
|
- self.num_w_ports*(self.write_nmos.active_width + self.rw_w_spacing) \
|
||||||
- self.num_r_ports*(self.read_port_width + self.port_spacing) \
|
- self.num_r_ports*(self.read_port_width + self.r_spacing) \
|
||||||
- self.bitline_offset - 0.5*self.m2_width
|
- self.bitline_offset - 0.5*self.m2_width
|
||||||
|
|
||||||
self.width = -2*self.leftmost_xpos
|
self.width = -2*self.leftmost_xpos
|
||||||
|
|
@ -370,11 +372,11 @@ class pbitcell(design.design):
|
||||||
for k in range(0,self.num_rw_ports):
|
for k in range(0,self.num_rw_ports):
|
||||||
# calculate read/write transistor offsets
|
# calculate read/write transistor offsets
|
||||||
left_readwrite_transistor_xpos = self.left_building_edge \
|
left_readwrite_transistor_xpos = self.left_building_edge \
|
||||||
- (k+1)*self.port_spacing \
|
- (k+1)*self.rw_w_spacing \
|
||||||
- (k+1)*self.readwrite_nmos.active_width
|
- (k+1)*self.readwrite_nmos.active_width
|
||||||
|
|
||||||
right_readwrite_transistor_xpos = self.right_building_edge \
|
right_readwrite_transistor_xpos = self.right_building_edge \
|
||||||
+ (k+1)*self.port_spacing \
|
+ (k+1)*self.rw_w_spacing \
|
||||||
+ k*self.readwrite_nmos.active_width
|
+ k*self.readwrite_nmos.active_width
|
||||||
|
|
||||||
# place read/write transistors
|
# place read/write transistors
|
||||||
|
|
@ -392,7 +394,7 @@ class pbitcell(design.design):
|
||||||
height=self.m1_width)
|
height=self.m1_width)
|
||||||
|
|
||||||
# add pins for RWBL and RWBR
|
# add pins for RWBL and RWBR
|
||||||
rwbl_xpos = left_readwrite_transistor_xpos - self.bitline_offset + self.m2_width
|
rwbl_xpos = left_readwrite_transistor_xpos - self.bitline_offset + 0.5*self.m2_width
|
||||||
self.rwbl_positions[k] = vector(rwbl_xpos, self.center_ypos)
|
self.rwbl_positions[k] = vector(rwbl_xpos, self.center_ypos)
|
||||||
self.add_layout_pin_rect_center(text=self.rw_bl_names[k],
|
self.add_layout_pin_rect_center(text=self.rw_bl_names[k],
|
||||||
layer="metal2",
|
layer="metal2",
|
||||||
|
|
@ -400,7 +402,7 @@ class pbitcell(design.design):
|
||||||
width=drc["minwidth_metal2"],
|
width=drc["minwidth_metal2"],
|
||||||
height=self.height)
|
height=self.height)
|
||||||
|
|
||||||
rwbr_xpos = right_readwrite_transistor_xpos + self.readwrite_nmos.active_width + self.bitline_offset - self.m2_width
|
rwbr_xpos = right_readwrite_transistor_xpos + self.readwrite_nmos.active_width + self.bitline_offset - 0.5*self.m2_width
|
||||||
self.rwbr_positions[k] = vector(rwbr_xpos, self.center_ypos)
|
self.rwbr_positions[k] = vector(rwbr_xpos, self.center_ypos)
|
||||||
self.add_layout_pin_rect_center(text=self.rw_br_names[k],
|
self.add_layout_pin_rect_center(text=self.rw_br_names[k],
|
||||||
layer="metal2",
|
layer="metal2",
|
||||||
|
|
@ -447,11 +449,11 @@ class pbitcell(design.design):
|
||||||
# Add transistors
|
# Add transistors
|
||||||
# calculate write transistor offsets
|
# calculate write transistor offsets
|
||||||
left_write_transistor_xpos = self.left_building_edge \
|
left_write_transistor_xpos = self.left_building_edge \
|
||||||
- (k+1)*self.port_spacing \
|
- (k+1)*self.rw_w_spacing \
|
||||||
- (k+1)*self.write_nmos.active_width
|
- (k+1)*self.write_nmos.active_width
|
||||||
|
|
||||||
right_write_transistor_xpos = self.right_building_edge \
|
right_write_transistor_xpos = self.right_building_edge \
|
||||||
+ (k+1)*self.port_spacing \
|
+ (k+1)*self.rw_w_spacing \
|
||||||
+ k*self.write_nmos.active_width
|
+ k*self.write_nmos.active_width
|
||||||
|
|
||||||
# add write transistors
|
# add write transistors
|
||||||
|
|
@ -469,7 +471,7 @@ class pbitcell(design.design):
|
||||||
height=self.m1_width)
|
height=self.m1_width)
|
||||||
|
|
||||||
# add pins for WBL and WBR
|
# add pins for WBL and WBR
|
||||||
wbl_xpos = left_write_transistor_xpos - self.bitline_offset + self.m2_width
|
wbl_xpos = left_write_transistor_xpos - self.bitline_offset + 0.5*self.m2_width
|
||||||
self.wbl_positions[k] = vector(wbl_xpos, self.center_ypos)
|
self.wbl_positions[k] = vector(wbl_xpos, self.center_ypos)
|
||||||
self.add_layout_pin_rect_center(text=self.w_bl_names[k],
|
self.add_layout_pin_rect_center(text=self.w_bl_names[k],
|
||||||
layer="metal2",
|
layer="metal2",
|
||||||
|
|
@ -477,7 +479,7 @@ class pbitcell(design.design):
|
||||||
width=drc["minwidth_metal2"],
|
width=drc["minwidth_metal2"],
|
||||||
height=self.height)
|
height=self.height)
|
||||||
|
|
||||||
wbr_xpos = right_write_transistor_xpos + self.write_nmos.active_width + self.bitline_offset - self.m2_width
|
wbr_xpos = right_write_transistor_xpos + self.write_nmos.active_width + self.bitline_offset - 0.5*self.m2_width
|
||||||
self.wbr_positions[k] = vector(wbr_xpos, self.center_ypos)
|
self.wbr_positions[k] = vector(wbr_xpos, self.center_ypos)
|
||||||
self.add_layout_pin_rect_center(text=self.w_br_names[k],
|
self.add_layout_pin_rect_center(text=self.w_br_names[k],
|
||||||
layer="metal2",
|
layer="metal2",
|
||||||
|
|
@ -541,11 +543,11 @@ class pbitcell(design.design):
|
||||||
for k in range(0,self.num_r_ports):
|
for k in range(0,self.num_r_ports):
|
||||||
# calculate transistor offsets
|
# calculate transistor offsets
|
||||||
left_read_transistor_xpos = self.left_building_edge \
|
left_read_transistor_xpos = self.left_building_edge \
|
||||||
- (k+1)*self.port_spacing \
|
- (k+1)*self.r_spacing \
|
||||||
- (k+1)*self.read_port_width
|
- (k+1)*self.read_port_width
|
||||||
|
|
||||||
right_read_transistor_xpos = self.right_building_edge \
|
right_read_transistor_xpos = self.right_building_edge \
|
||||||
+ (k+1)*self.port_spacing \
|
+ (k+1)*self.r_spacing \
|
||||||
+ k*self.read_port_width
|
+ k*self.read_port_width
|
||||||
|
|
||||||
# add read-access transistors
|
# add read-access transistors
|
||||||
|
|
@ -568,7 +570,7 @@ class pbitcell(design.design):
|
||||||
height=self.m1_width)
|
height=self.m1_width)
|
||||||
|
|
||||||
# add pins for RBL and RBR
|
# add pins for RBL and RBR
|
||||||
rbl_xpos = left_read_transistor_xpos - self.bitline_offset + self.m2_width
|
rbl_xpos = left_read_transistor_xpos - self.bitline_offset + 0.5*self.m2_width
|
||||||
self.rbl_positions[k] = vector(rbl_xpos, self.center_ypos)
|
self.rbl_positions[k] = vector(rbl_xpos, self.center_ypos)
|
||||||
self.add_layout_pin_rect_center(text=self.r_bl_names[k],
|
self.add_layout_pin_rect_center(text=self.r_bl_names[k],
|
||||||
layer="metal2",
|
layer="metal2",
|
||||||
|
|
@ -576,7 +578,7 @@ class pbitcell(design.design):
|
||||||
width=drc["minwidth_metal2"],
|
width=drc["minwidth_metal2"],
|
||||||
height=self.height)
|
height=self.height)
|
||||||
|
|
||||||
rbr_xpos = right_read_transistor_xpos + self.read_port_width + self.bitline_offset - self.m2_width
|
rbr_xpos = right_read_transistor_xpos + self.read_port_width + self.bitline_offset - 0.5*self.m2_width
|
||||||
self.rbr_positions[k] = vector(rbr_xpos, self.center_ypos)
|
self.rbr_positions[k] = vector(rbr_xpos, self.center_ypos)
|
||||||
self.add_layout_pin_rect_center(text=self.r_br_names[k],
|
self.add_layout_pin_rect_center(text=self.r_br_names[k],
|
||||||
layer="metal2",
|
layer="metal2",
|
||||||
|
|
@ -692,7 +694,11 @@ class pbitcell(design.design):
|
||||||
self.add_contact_center(layers=("metal1", "via1", "metal2"),
|
self.add_contact_center(layers=("metal1", "via1", "metal2"),
|
||||||
offset=position)
|
offset=position)
|
||||||
|
|
||||||
supply_offset = vector(position.x, self.gnd_position.y)
|
if position.x > 0:
|
||||||
|
contact_correct = 0.5*contact.m1m2.height
|
||||||
|
else:
|
||||||
|
contact_correct = -0.5*contact.m1m2.height
|
||||||
|
supply_offset = vector(position.x + contact_correct, self.gnd_position.y)
|
||||||
self.add_contact_center(layers=("metal1", "via1", "metal2"),
|
self.add_contact_center(layers=("metal1", "via1", "metal2"),
|
||||||
offset=supply_offset,
|
offset=supply_offset,
|
||||||
rotate=90)
|
rotate=90)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue