OpenRAM/compiler/modules/ms_flop_array.py

137 lines
4.8 KiB
Python

import debug
import design
from tech import drc
from math import log
from vector import vector
from globals import OPTS
class ms_flop_array(design.design):
"""
An Array of D-Flipflops used for to store Data_in & Data_out of
Write_driver & Sense_amp, address inputs of column_mux &
hierdecoder
"""
def __init__(self, columns, word_size, name=""):
self.columns = columns
self.word_size = word_size
if name=="":
name = "flop_array_c{0}_w{1}".format(columns,word_size)
design.design.__init__(self, name)
debug.info(1, "Creating {}".format(self.name))
self.words_per_row = int(self.columns / self.word_size)
self.create_netlist()
if not OPTS.netlist_only:
self.create_layout()
def create_netlist(self):
self.add_modules()
self.add_pins()
self.create_ms_flop_array()
def create_layout(self):
self.width = self.columns * self.ms.width
self.height = self.ms.height
self.place_ms_flop_array()
self.add_layout_pins()
self.DRC_LVS()
def add_modules(self):
from importlib import reload
c = reload(__import__(OPTS.ms_flop))
self.mod_ms_flop = getattr(c, OPTS.ms_flop)
self.ms = self.mod_ms_flop("ms_flop")
self.add_mod(self.ms)
def add_pins(self):
for i in range(self.word_size):
self.add_pin("din[{0}]".format(i))
for i in range(self.word_size):
self.add_pin("dout[{0}]".format(i))
self.add_pin("dout_bar[{0}]".format(i))
self.add_pin("clk")
self.add_pin("vdd")
self.add_pin("gnd")
def create_ms_flop_array(self):
self.ms_inst={}
for i in range(0,self.columns,self.words_per_row):
name = "Xdff{0}".format(i)
index = int(i/self.words_per_row)
self.ms_inst[index]=self.add_inst(name=name,
mod=self.ms)
self.connect_inst(["din[{0}]".format(index),
"dout[{0}]".format(index),
"dout_bar[{0}]".format(index),
"clk",
"vdd", "gnd"])
def place_ms_flop_array(self):
for i in range(0,self.columns,self.words_per_row):
index = int(i/self.words_per_row)
if (i % 2 == 0 or self.words_per_row>1):
base = vector(i*self.ms.width,0)
mirror = "R0"
else:
base = vector((i+1)*self.ms.width,0)
mirror = "MY"
self.ms_inst[index].place(offset=base,
mirror=mirror)
def add_layout_pins(self):
for i in range(self.word_size):
# Route both supplies
for n in ["vdd", "gnd"]:
for supply_pin in self.ms_inst[i].get_pins(n):
pin_pos = supply_pin.center()
self.add_via_center(layers=("metal2", "via2", "metal3"),
offset=pin_pos)
self.add_layout_pin_rect_center(text=n,
layer="metal3",
offset=pin_pos)
din_pins = self.ms_inst[i].get_pins("din")
for din_pin in din_pins:
self.add_layout_pin(text="din[{}]".format(i),
layer=din_pin.layer,
offset=din_pin.ll(),
width=din_pin.width(),
height=din_pin.height())
dout_pin = self.ms_inst[i].get_pin("dout")
self.add_layout_pin(text="dout[{}]".format(i),
layer="metal2",
offset=dout_pin.ll(),
width=dout_pin.width(),
height=dout_pin.height())
doutbar_pin = self.ms_inst[i].get_pin("dout_bar")
self.add_layout_pin(text="dout_bar[{}]".format(i),
layer="metal2",
offset=doutbar_pin.ll(),
width=doutbar_pin.width(),
height=doutbar_pin.height())
# Continous clk rail along with label.
self.add_layout_pin(text="clk",
layer="metal1",
offset=self.ms_inst[0].get_pin("clk").ll().scale(0,1),
width=self.width,
height=drc["minwidth_metal1"])
def analytical_delay(self, slew, load=0.0):
return self.ms.analytical_delay(slew=slew, load=load)