Placed wmask dff and added connections for wmask pins.

This commit is contained in:
jsowash 2019-08-14 11:45:22 -07:00
parent 0d7170eb95
commit 858fbb062d
3 changed files with 139 additions and 19 deletions

View File

@ -121,7 +121,7 @@ class bank(design.design):
self.route_column_address_lines(port)
self.route_control_lines(port)
if self.num_banks > 1:
self.route_bank_select(port)
self.route_bank_select(port)
self.route_supplies()
@ -700,6 +700,15 @@ class bank(design.design):
offset=data_pin.center(),
height=data_pin.height(),
width=data_pin.width())
#
# if self.word_size is not None:
# for bit in range(self.num_wmasks):
# wmask_pin = self.port_data_inst[port].get_pin("bank_wmask_{0}".format(bit))
# self.add_layout_pin_rect_center(text="bank_wmask{0}_{1}".format(port, bit),
# layer=wmask_pin.layer,
# offset=wmask_pin.center(),
# height=wmask_pin.height(),
# width=wmask_pin.width())
def route_port_address_in(self, port):
@ -711,8 +720,9 @@ class bank(design.design):
decoder_name = "addr_{}".format(row)
addr_name = "addr{0}_{1}".format(port,addr_idx)
self.copy_layout_pin(self.port_address_inst[port], decoder_name, addr_name)
def route_port_data_in(self, port):
""" Connecting port data in """
@ -720,6 +730,14 @@ class bank(design.design):
data_name = "din_{}".format(row)
din_name = "din{0}_{1}".format(port,row)
self.copy_layout_pin(self.port_data_inst[port], data_name, din_name)
if self.word_size is not None:
for row in range(self.num_wmasks):
wmask_name = "bank_wmask_{}".format(row)
bank_wmask_name = "bank_wmask{0}_{1}".format(port, row)
self.copy_layout_pin(self.port_data_inst[port], wmask_name, bank_wmask_name)
def channel_route_bitlines(self, inst1, inst2, num_bits,
inst1_bl_name="bl_{}", inst1_br_name="br_{}",

View File

@ -86,9 +86,19 @@ class sram_1bank(sram_base):
data_pos[port] = vector(self.bank.bank_array_ll.x,
-max_gap_size - self.dff.height)
self.data_dff_insts[port].place(data_pos[port])
else:
data_pos[port] = vector(self.bank.bank_array_ll.x,0)
# Add the write mask flops below the din flops.
if self.write_size is not None:
if port in self.write_ports:
wmask_pos[port] = vector(self.bank.bank_array_ll.x,
- 2*max_gap_size - 2*self.dff.height)
self.wmask_dff_insts[port].place(wmask_pos[port])
else:
wmask_pos[port] = vector(self.bank.bank_array_ll.x, 0)
# Add the col address flops below the bank to the left of the lower-left of bank array
if self.col_addr_dff:
col_addr_pos[port] = vector(self.bank.bank_array_ll.x - self.col_addr_dff_insts[port].width - self.bank.m2_gap,
@ -125,14 +135,14 @@ class sram_1bank(sram_base):
-max_gap_size - self.data_dff_insts[port].height)
self.data_dff_insts[port].place(data_pos[port])
# Add the write mask flops below the din flops.
if self.write_size is not None:
if port in self.write_ports:
wmask_pos[port] = vector(self.bank.bank_array_ll.x,
-max_gap_size - self.wmask_dff_insts[port].height)
# wmask_pos[port] = vector(self.bank.bank_array_ll.x - self.control_logic_insts[port].width,
# -max_gap_size - self.wmask_dff_insts[port].height)
self.wmask_dff_insts[port].place(wmask_pos[port])
# # Add the write mask flops below the din flops.
# if self.write_size is not None:
# if port in self.write_ports:
# wmask_pos[port] = vector(self.bank.bank_array_ll.x,
# -max_gap_size - self.wmask_dff_insts[port].height)
# # wmask_pos[port] = vector(self.bank.bank_array_ll.x - self.control_logic_insts[port].width,
# # -max_gap_size - self.wmask_dff_insts[port].height)
# self.wmask_dff_insts[port].place(wmask_pos[port])
if len(self.all_ports)>1:
@ -149,6 +159,13 @@ class sram_1bank(sram_base):
self.bank.height + max_gap_size + self.dff.height)
self.data_dff_insts[port].place(data_pos[port], mirror="MX")
# Add the write mask flops below the din flops.
if self.write_size is not None:
if port in self.write_ports:
wmask_pos[port] = vector(self.bank.bank_array_ur.x - self.data_dff_insts[port].width,
self.bank.height + 2*max_gap_size + 2*self.dff.height)
self.wmask_dff_insts[port].place(wmask_pos[port], mirror="MX")
# Add the write mask flops to the left of the din flops.
if self.write_size is not None:
if port in self.write_ports:
@ -191,13 +208,13 @@ class sram_1bank(sram_base):
self.bank.height + max_gap_size + self.dff.height)
self.data_dff_insts[port].place(data_pos[port], mirror="MX")
# Add the write mask flops to the left of the din flops.
if self.write_size is not None:
if port in self.write_ports:
wmask_pos[port] = vector(self.bank.bank_array_ur.x - self.data_dff_insts[port].width,
self.bank.height + max_gap_size + self.data_dff_insts[port].height)
self.wmask_dff_insts[port].place(wmask_pos[port], mirror="MX")
# # Add the write mask flops to the left of the din flops.
# if self.write_size is not None:
# if port in self.write_ports:
# wmask_pos[port] = vector(self.bank.bank_array_ur.x - self.data_dff_insts[port].width,
# self.bank.height + max_gap_size + self.data_dff_insts[port].height)
# self.wmask_dff_insts[port].place(wmask_pos[port], mirror="MX")
#
def add_layout_pins(self):
"""
@ -222,6 +239,10 @@ class sram_1bank(sram_base):
if port in self.write_ports:
for bit in range(self.word_size):
self.copy_layout_pin(self.data_dff_insts[port], "din_{}".format(bit), "DIN{0}[{1}]".format(port,bit))
if self.write_size is not None:
for bit in range(self.num_wmasks):
self.copy_layout_pin(self.wmask_dff_insts[port], "din_{}".format(bit), "wmask{0}[{1}]".format(port,bit))
def route_layout(self):
""" Route a single bank SRAM """
@ -238,6 +259,7 @@ class sram_1bank(sram_base):
self.route_col_addr_dff()
self.route_data_dff()
self.route_wmask_dff()
def route_clk(self):
""" Route the clock network """
@ -290,6 +312,15 @@ class sram_1bank(sram_base):
self.add_path("metal2",[mid_pos, clk_steiner_pos], width=max(m2m3.width,m2m3.height))
self.add_wire(("metal3","via2","metal2"),[data_dff_clk_pos, mid_pos, clk_steiner_pos])
if self.write_size is not None:
wmask_dff_clk_pin = self.wmask_dff_insts[port].get_pin("clk")
wmask_dff_clk_pos = wmask_dff_clk_pin.center()
mid_pos = vector(clk_steiner_pos.x, wmask_dff_clk_pos.y)
# In some designs, the steiner via will be too close to the mid_pos via
# so make the wire as wide as the contacts
self.add_path("metal2", [mid_pos, clk_steiner_pos], width=max(m2m3.width, m2m3.height))
self.add_wire(("metal3", "via2", "metal2"), [wmask_dff_clk_pos, mid_pos, clk_steiner_pos])
def route_control_logic(self):
""" Route the control logic pins that are not inputs """
@ -367,7 +398,24 @@ class sram_1bank(sram_base):
route_map = list(zip(bank_pins, dff_pins))
self.create_horizontal_channel_route(route_map, offset)
def route_wmask_dff(self):
""" Connect the output of the wmask flops to the write mask AND array """
# This is where the channel will start (y-dimension at least)
for port in self.write_ports:
if port % 2:
offset = self.wmask_dff_insts[port].ll() - vector(0, (self.word_size + 2) * self.m1_pitch)
else:
offset = self.wmask_dff_insts[port].ul() + vector(0, 2 * self.m1_pitch)
dff_names = ["dout_{}".format(x) for x in range(self.num_wmasks)]
dff_pins = [self.wmask_dff_insts[port].get_pin(x) for x in dff_names]
bank_names = ["bank_wmask{0}_{1}".format(port, x) for x in range(self.num_wmasks)]
bank_pins = [self.bank_inst.get_pin(x) for x in bank_names]
route_map = list(zip(bank_pins, dff_pins))
self.create_horizontal_channel_route(route_map, offset)
def add_lvs_correspondence_points(self):

View File

@ -0,0 +1,54 @@
#!/usr/bin/env python3
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2019 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.
#
import unittest
from testutils import *
import sys, os
sys.path.append(os.getenv("OPENRAM_HOME"))
import globals
from globals import OPTS
from sram_factory import factory
import debug
# @unittest.skip("SKIPPING 20_sram_1bank_nomux_wmask_test")
class sram_1bank_nomux_wmask_test(openram_test):
def runTest(self):
globals.init_openram("config_{0}".format(OPTS.tech_name))
from sram_config import sram_config
c = sram_config(word_size=8,
write_size=4,
num_words=16,
num_banks=1)
c.words_per_row = 1
c.recompute_sizes()
debug.info(1, "Layout test for {}rw,{}r,{}w sram "
"with {} bit words, {} words, {} bit writes, {} words per "
"row, {} banks".format(OPTS.num_rw_ports,
OPTS.num_r_ports,
OPTS.num_w_ports,
c.word_size,
c.num_words,
c.write_size,
c.words_per_row,
c.num_banks))
a = factory.create(module_type="sram", sram_config=c)
self.local_check(a, final_verification=True)
globals.end_openram()
# run the test from the command line
if __name__ == "__main__":
(OPTS, args) = globals.parse_args()
del sys.argv[1:]
header(__file__, OPTS.tech_name)
unittest.main(testRunner=debugTestRunner())