mirror of https://github.com/VLSIDA/OpenRAM.git
Adding replica_pbitcell and test for multi-ported purposes. Altering replica bitline and test to accomodate.
This commit is contained in:
parent
f03cd7c3ba
commit
e0b9989d85
|
|
@ -144,6 +144,7 @@ class replica_bitline(design.design):
|
||||||
self.connect_inst(temp)
|
self.connect_inst(temp)
|
||||||
|
|
||||||
self.wl_list = self.rbl.cell.list_all_wl_names()
|
self.wl_list = self.rbl.cell.list_all_wl_names()
|
||||||
|
self.bl_list = self.rbl.cell.list_write_bl_names()
|
||||||
|
|
||||||
def place_modules(self):
|
def place_modules(self):
|
||||||
""" Add all of the module instances in the logical netlist """
|
""" Add all of the module instances in the logical netlist """
|
||||||
|
|
@ -178,14 +179,20 @@ class replica_bitline(design.design):
|
||||||
wl = self.wl_list[0]+"[{}]".format(row)
|
wl = self.wl_list[0]+"[{}]".format(row)
|
||||||
pin = self.rbl_inst.get_pin(wl)
|
pin = self.rbl_inst.get_pin(wl)
|
||||||
|
|
||||||
# Route the connection to the right so that it doesn't interfere
|
# Route the connection to the right so that it doesn't interfere with the cells
|
||||||
# with the cells
|
# Wordlines may be close to each other when tiled, so gnd connections are routed in opposite directions
|
||||||
|
if row % 2 == 0:
|
||||||
|
vertical_extension = vector(0, 1.5*drc["minwidth_metal1"] + 0.5*contact.m1m2.height)
|
||||||
|
else:
|
||||||
|
vertical_extension = vector(0, -1.5*drc["minwidth_metal1"] - 1.5*contact.m1m2.height)
|
||||||
|
|
||||||
pin_right = pin.rc()
|
pin_right = pin.rc()
|
||||||
pin_extension = pin_right + vector(self.m1_pitch,0)
|
pin_extension1 = pin_right + vector(self.m3_pitch,0)
|
||||||
|
pin_extension2 = pin_extension1 + vertical_extension
|
||||||
if pin.layer != "metal1":
|
if pin.layer != "metal1":
|
||||||
continue
|
continue
|
||||||
self.add_path("metal1", [pin_right, pin_extension])
|
self.add_path("metal1", [pin_right, pin_extension1, pin_extension2])
|
||||||
self.add_power_pin("gnd", pin_extension)
|
self.add_power_pin("gnd", pin_extension2)
|
||||||
|
|
||||||
|
|
||||||
def route_supplies(self):
|
def route_supplies(self):
|
||||||
|
|
@ -243,11 +250,13 @@ class replica_bitline(design.design):
|
||||||
|
|
||||||
# 3. Route the contact of previous route to the bitcell WL
|
# 3. Route the contact of previous route to the bitcell WL
|
||||||
# route bend of previous net to bitcell WL
|
# route bend of previous net to bitcell WL
|
||||||
wl_offset = self.rbc_inst.get_pin("wl").lc()
|
wl_offset = self.rbc_inst.get_pin(self.wl_list[0]).lc()
|
||||||
xmid_point= 0.5*(wl_offset.x+contact_offset.x)
|
wl_mid1 = wl_offset - vector(1.5*drc["minwidth_metal1"], 0)
|
||||||
wl_mid1 = vector(xmid_point,contact_offset.y)
|
wl_mid2 = vector(wl_mid1.x, contact_offset.y)
|
||||||
wl_mid2 = vector(xmid_point,wl_offset.y)
|
#xmid_point= 0.5*(wl_offset.x+contact_offset.x)
|
||||||
self.add_path("metal1", [contact_offset, wl_mid1, wl_mid2, wl_offset])
|
#wl_mid1 = vector(xmid_point,contact_offset.y)
|
||||||
|
#wl_mid2 = vector(xmid_point,wl_offset.y)
|
||||||
|
self.add_path("metal1", [wl_offset, wl_mid1, wl_mid2, contact_offset])
|
||||||
|
|
||||||
# DRAIN ROUTE
|
# DRAIN ROUTE
|
||||||
# Route the drain to the vdd rail
|
# Route the drain to the vdd rail
|
||||||
|
|
@ -262,7 +271,7 @@ class replica_bitline(design.design):
|
||||||
|
|
||||||
# Route the connection of the source route to the RBL bitline (left)
|
# Route the connection of the source route to the RBL bitline (left)
|
||||||
# Via will go halfway down from the bitcell
|
# Via will go halfway down from the bitcell
|
||||||
bl_offset = self.rbc_inst.get_pin("bl").bc()
|
bl_offset = self.rbc_inst.get_pin(self.bl_list[0]).bc()
|
||||||
# Route down a pitch so we can use M2 routing
|
# Route down a pitch so we can use M2 routing
|
||||||
bl_down_offset = bl_offset - vector(0, self.m2_pitch)
|
bl_down_offset = bl_offset - vector(0, self.m2_pitch)
|
||||||
self.add_path("metal2",[source_offset, bl_down_offset, bl_offset])
|
self.add_path("metal2",[source_offset, bl_down_offset, bl_offset])
|
||||||
|
|
|
||||||
|
|
@ -346,6 +346,7 @@ class pbitcell(design.design):
|
||||||
self.inverter_pmos_left.place([left_inverter_xpos, inverter_pmos_ypos])
|
self.inverter_pmos_left.place([left_inverter_xpos, inverter_pmos_ypos])
|
||||||
self.inverter_pmos_right.place([right_inverter_xpos, inverter_pmos_ypos])
|
self.inverter_pmos_right.place([right_inverter_xpos, inverter_pmos_ypos])
|
||||||
|
|
||||||
|
|
||||||
def route_storage(self):
|
def route_storage(self):
|
||||||
"""
|
"""
|
||||||
Routes inputs and outputs of inverters to cross couple them
|
Routes inputs and outputs of inverters to cross couple them
|
||||||
|
|
@ -394,13 +395,13 @@ class pbitcell(design.design):
|
||||||
height=contact.well.second_layer_width)
|
height=contact.well.second_layer_width)
|
||||||
|
|
||||||
vdd_ypos = self.inverter_nmos.active_height + self.inverter_gap + self.inverter_pmos.active_height \
|
vdd_ypos = self.inverter_nmos.active_height + self.inverter_gap + self.inverter_pmos.active_height \
|
||||||
+ drc["active_to_body_active"] + 0.5*(drc["minwidth_tx"] - drc["minwidth_metal1"])
|
+ drc["active_to_body_active"]
|
||||||
self.vdd_position = vector(self.leftmost_xpos, vdd_ypos)
|
self.vdd_position = vector(self.leftmost_xpos, vdd_ypos)
|
||||||
self.vdd = self.add_layout_pin(text="vdd",
|
self.vdd = self.add_layout_pin(text="vdd",
|
||||||
layer="metal1",
|
layer="metal1",
|
||||||
offset=self.vdd_position,
|
offset=self.vdd_position,
|
||||||
width=self.width,
|
width=self.width,
|
||||||
height=drc["minwidth_metal1"])
|
height=contact.well.second_layer_width)
|
||||||
|
|
||||||
# Connect inverters to rails
|
# Connect inverters to rails
|
||||||
# connect inverter nmos to gnd
|
# connect inverter nmos to gnd
|
||||||
|
|
@ -848,7 +849,7 @@ class pbitcell(design.design):
|
||||||
# add read-access transistors
|
# add read-access transistors
|
||||||
self.read_access_nmos_left[k] = self.add_inst(name="read_access_nmos_left{}".format(k),
|
self.read_access_nmos_left[k] = self.add_inst(name="read_access_nmos_left{}".format(k),
|
||||||
mod=self.read_nmos)
|
mod=self.read_nmos)
|
||||||
self.connect_inst(["RA_to_R_left{}".format(k), " Q_bar", "gnd", "gnd"])
|
self.connect_inst(["RA_to_R_left{}".format(k), "Q_bar", "gnd", "gnd"])
|
||||||
|
|
||||||
self.read_access_nmos_right[k] = self.add_inst(name="read_access_nmos_right{}".format(k),
|
self.read_access_nmos_right[k] = self.add_inst(name="read_access_nmos_right{}".format(k),
|
||||||
mod=self.read_nmos)
|
mod=self.read_nmos)
|
||||||
|
|
@ -1156,7 +1157,7 @@ class pbitcell(design.design):
|
||||||
well_type="p")
|
well_type="p")
|
||||||
|
|
||||||
# connect nimplants to vdd
|
# connect nimplants to vdd
|
||||||
offset = vector(0, self.vdd_position.y + 0.5*drc["minwidth_metal1"])
|
offset = vector(0, self.vdd_position.y + 0.5*contact.well.second_layer_width)
|
||||||
self.add_contact_center(layers=("active", "contact", "metal1"),
|
self.add_contact_center(layers=("active", "contact", "metal1"),
|
||||||
offset=offset,
|
offset=offset,
|
||||||
rotate=90,
|
rotate=90,
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,46 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Run a regression test on a replica pbitcell
|
||||||
|
"""
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
from testutils import header,openram_test
|
||||||
|
import sys,os
|
||||||
|
sys.path.append(os.path.join(sys.path[0],".."))
|
||||||
|
import globals
|
||||||
|
from globals import OPTS
|
||||||
|
import debug
|
||||||
|
|
||||||
|
class replica_pbitcell_test(openram_test):
|
||||||
|
|
||||||
|
def runTest(self):
|
||||||
|
globals.init_openram("config_20_{0}".format(OPTS.tech_name))
|
||||||
|
import replica_pbitcell
|
||||||
|
import tech
|
||||||
|
|
||||||
|
# check precharge in multi-port
|
||||||
|
OPTS.bitcell = "pbitcell"
|
||||||
|
OPTS.num_rw_ports = 1
|
||||||
|
OPTS.num_r_ports = 0
|
||||||
|
OPTS.num_w_ports = 0
|
||||||
|
|
||||||
|
debug.info(2, "Checking replica bitcell using pbitcell (small cell)")
|
||||||
|
tx = replica_pbitcell.replica_pbitcell()
|
||||||
|
self.local_check(tx)
|
||||||
|
|
||||||
|
OPTS.num_rw_ports = 1
|
||||||
|
OPTS.num_r_ports = 1
|
||||||
|
OPTS.num_w_ports = 1
|
||||||
|
|
||||||
|
debug.info(2, "Checking replica bitcell using pbitcell (large cell)")
|
||||||
|
tx = replica_pbitcell.replica_pbitcell()
|
||||||
|
self.local_check(tx)
|
||||||
|
|
||||||
|
globals.end_openram()
|
||||||
|
|
||||||
|
# instantiate a copy of the class to actually run the test
|
||||||
|
if __name__ == "__main__":
|
||||||
|
(OPTS, args) = globals.parse_args()
|
||||||
|
del sys.argv[1:]
|
||||||
|
header(__file__, OPTS.tech_name)
|
||||||
|
unittest.main()
|
||||||
|
|
@ -17,6 +17,27 @@ class replica_bitline_test(openram_test):
|
||||||
globals.init_openram("config_20_{0}".format(OPTS.tech_name))
|
globals.init_openram("config_20_{0}".format(OPTS.tech_name))
|
||||||
import replica_bitline
|
import replica_bitline
|
||||||
|
|
||||||
|
# check replica bitline in single port
|
||||||
|
stages=4
|
||||||
|
fanout=4
|
||||||
|
rows=13
|
||||||
|
debug.info(2, "Testing RBL with {0} FO4 stages, {1} rows".format(stages,rows))
|
||||||
|
a = replica_bitline.replica_bitline(stages,fanout,rows)
|
||||||
|
self.local_check(a)
|
||||||
|
|
||||||
|
stages=8
|
||||||
|
rows=100
|
||||||
|
debug.info(2, "Testing RBL with {0} FO4 stages, {1} rows".format(stages,rows))
|
||||||
|
a = replica_bitline.replica_bitline(stages,fanout,rows)
|
||||||
|
self.local_check(a)
|
||||||
|
|
||||||
|
# check replica bitline in multi-port
|
||||||
|
OPTS.bitcell = "pbitcell"
|
||||||
|
OPTS.replica_bitcell = "replica_pbitcell"
|
||||||
|
OPTS.num_rw_ports = 1
|
||||||
|
OPTS.num_w_ports = 0
|
||||||
|
OPTS.num_r_ports = 0
|
||||||
|
|
||||||
stages=4
|
stages=4
|
||||||
fanout=4
|
fanout=4
|
||||||
rows=13
|
rows=13
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue