2016-11-08 18:57:35 +01:00
|
|
|
from tech import drc
|
|
|
|
|
import debug
|
|
|
|
|
import design
|
2016-11-22 21:23:55 +01:00
|
|
|
from nand_3 import nand_3
|
2016-11-08 18:57:35 +01:00
|
|
|
from vector import vector
|
|
|
|
|
from hierarchical_predecode import hierarchical_predecode
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class hierarchical_predecode3x8(hierarchical_predecode):
|
|
|
|
|
"""
|
|
|
|
|
Pre 3x8 decoder used in hierarchical_decoder.
|
|
|
|
|
"""
|
|
|
|
|
def __init__(self, nmos_width, cellname):
|
|
|
|
|
hierarchical_predecode.__init__(self, nmos_width, cellname, 3)
|
|
|
|
|
|
|
|
|
|
self.add_pins()
|
|
|
|
|
self.create_modules()
|
|
|
|
|
self.setup_constrains()
|
|
|
|
|
self.create_layout()
|
|
|
|
|
self.route()
|
|
|
|
|
|
2016-11-22 21:23:55 +01:00
|
|
|
def create_nand(self):
|
|
|
|
|
self.nand = nand_3(name="a_nand_3",
|
|
|
|
|
nmos_width=self.nmos_width,
|
|
|
|
|
height=self.bitcell_height)
|
|
|
|
|
|
|
|
|
|
def set_rail_height(self):
|
|
|
|
|
self.rail_height = (self.number_of_outputs * self.nand.height
|
|
|
|
|
- 1.5 * drc["minwidth_metal2"])
|
2016-11-08 18:57:35 +01:00
|
|
|
def create_layout(self):
|
|
|
|
|
self.create_rails()
|
|
|
|
|
self.add_output_inverters()
|
|
|
|
|
connections=[["A[0]", "A[1]", "A[2]", "Z[7]", "vdd", "gnd"],
|
|
|
|
|
["A[0]", "A[1]", "B[2]", "Z[6]", "vdd", "gnd"],
|
|
|
|
|
["A[0]", "B[1]", "A[2]", "Z[5]", "vdd", "gnd"],
|
|
|
|
|
["A[0]", "B[1]", "B[2]", "Z[4]", "vdd", "gnd"],
|
|
|
|
|
["B[0]", "A[1]", "A[2]", "Z[3]", "vdd", "gnd"],
|
|
|
|
|
["B[0]", "A[1]", "B[2]", "Z[2]", "vdd", "gnd"],
|
|
|
|
|
["B[0]", "B[1]", "A[2]", "Z[1]", "vdd", "gnd"],
|
|
|
|
|
["B[0]", "B[1]", "B[2]", "Z[0]", "vdd", "gnd"]]
|
|
|
|
|
self.add_nand(connections)
|
|
|
|
|
|
2016-11-22 21:23:55 +01:00
|
|
|
def set_height(self):
|
|
|
|
|
self.height = 8 * self.nand.height
|
|
|
|
|
|
|
|
|
|
def cal_input_inverters_output(self,setup,output_shift,inv_rout):
|
|
|
|
|
y_dir,inv_in_offset,inv_out_offset,inv_vdd_offset,inv_gnd_offset = setup
|
|
|
|
|
correct = y_dir * (output_shift + drc["minwidth_metal1"])
|
2016-11-08 18:57:35 +01:00
|
|
|
|
2016-11-22 21:23:55 +01:00
|
|
|
out_offset = inv_out_offset + vector(0, output_shift + correct)
|
|
|
|
|
vertical1 = out_offset
|
|
|
|
|
vertical2 = (vertical1.scale(1, 0) + inv_vdd_offset.scale(0, 1)
|
|
|
|
|
+ vector(0, - correct))
|
|
|
|
|
horizontal1 = vertical1
|
|
|
|
|
horizontal2 = vector(self.rails_x_offset[inv_rout + 5] + drc["minwidth_metal2"],
|
|
|
|
|
vertical2.y)
|
|
|
|
|
return [[vertical1,vertical2],[horizontal1,horizontal2]]
|
2016-11-08 18:57:35 +01:00
|
|
|
|
2016-11-22 21:23:55 +01:00
|
|
|
def set_output_shift(self):
|
|
|
|
|
return 1.5 * drc["minwidth_metal1"]
|
2016-11-08 18:57:35 +01:00
|
|
|
|
2016-11-22 21:23:55 +01:00
|
|
|
def get_nand_input_line_combination(self):
|
|
|
|
|
combination = [[5, 6, 7], [5, 6, 10],
|
|
|
|
|
[5, 9, 7], [5, 9, 10],
|
|
|
|
|
[8, 6, 7], [8, 6, 10],
|
|
|
|
|
[8, 9, 7], [8, 9, 10]]
|
|
|
|
|
return combination
|
2016-11-08 18:57:35 +01:00
|
|
|
|
2016-11-22 21:23:55 +01:00
|
|
|
def create_y_offsets(self,k):
|
|
|
|
|
if (k % 2 == 0):
|
|
|
|
|
y_off = k * (self.nand.height)
|
|
|
|
|
y_dir =1
|
|
|
|
|
correct = [0,0,self.contact_shift]
|
|
|
|
|
else:
|
|
|
|
|
y_off = 2 * self.inv.height - drc["minwidth_metal1"] + (k - 1) * (self.nand.height)
|
|
|
|
|
y_dir = -1
|
|
|
|
|
correct = [0,self.contact_shift,0]
|
|
|
|
|
yoffset_nand_in = [y_off + y_dir*self.nand.A_position[1],
|
|
|
|
|
y_off + y_dir*self.nand.B_position[1],
|
|
|
|
|
y_off + y_dir*self.nand.C_position[1]]
|
|
|
|
|
return yoffset_nand_in, correct
|
2016-11-08 18:57:35 +01:00
|
|
|
|
2016-11-22 21:23:55 +01:00
|
|
|
def get_via_correct(self):
|
|
|
|
|
return vector(0, self.via_shift+self.contact_shift)
|
2016-11-08 18:57:35 +01:00
|
|
|
|
2016-11-22 21:23:55 +01:00
|
|
|
def get_vertical_metal(self):
|
|
|
|
|
return "metal2"
|
|
|
|
|
|
|
|
|
|
def get_via_y(self):
|
2016-11-08 18:57:35 +01:00
|
|
|
yoffset = (self.number_of_outputs * self.inv.height
|
|
|
|
|
- 0.5 * drc["minwidth_metal1"])
|
2016-11-22 21:23:55 +01:00
|
|
|
return yoffset
|