mirror of https://github.com/VLSIDA/OpenRAM.git
Fix control logic routing.
This commit is contained in:
parent
d36f14b408
commit
bac684a82a
|
|
@ -343,11 +343,11 @@ class control_logic(design.design):
|
||||||
|
|
||||||
# list of output control signals (for making a vertical bus)
|
# list of output control signals (for making a vertical bus)
|
||||||
if self.port_type == "rw":
|
if self.port_type == "rw":
|
||||||
self.internal_bus_list = ["gated_clk_bar", "gated_clk_buf", "we", "clk_buf", "we_bar", "cs"]
|
self.internal_bus_list = ["rbl_bl_delay_bar", "rbl_bl_delay", "gated_clk_bar", "gated_clk_buf", "we", "clk_buf", "we_bar", "cs"]
|
||||||
elif self.port_type == "r":
|
elif self.port_type == "r":
|
||||||
self.internal_bus_list = ["gated_clk_bar", "gated_clk_buf", "clk_buf", "cs_bar", "cs"]
|
self.internal_bus_list = ["rbl_bl_delay_bar", "rbl_bl_delay", "gated_clk_bar", "gated_clk_buf", "clk_buf", "cs_bar", "cs"]
|
||||||
else:
|
else:
|
||||||
self.internal_bus_list = ["gated_clk_bar", "gated_clk_buf", "clk_buf", "cs"]
|
self.internal_bus_list = ["rbl_bl_delay_bar", "rbl_bl_delay", "gated_clk_bar", "gated_clk_buf", "clk_buf", "cs"]
|
||||||
# leave space for the bus plus one extra space
|
# leave space for the bus plus one extra space
|
||||||
self.internal_bus_width = (len(self.internal_bus_list)+1)*self.m2_pitch
|
self.internal_bus_width = (len(self.internal_bus_list)+1)*self.m2_pitch
|
||||||
|
|
||||||
|
|
@ -381,6 +381,7 @@ class control_logic(design.design):
|
||||||
self.create_gated_clk_buf_row()
|
self.create_gated_clk_buf_row()
|
||||||
self.create_wlen_row()
|
self.create_wlen_row()
|
||||||
if (self.port_type == "rw") or (self.port_type == "w"):
|
if (self.port_type == "rw") or (self.port_type == "w"):
|
||||||
|
self.create_rbl_delay_row()
|
||||||
self.create_wen_row()
|
self.create_wen_row()
|
||||||
if (self.port_type == "rw") or (self.port_type == "r"):
|
if (self.port_type == "rw") or (self.port_type == "r"):
|
||||||
self.create_sen_row()
|
self.create_sen_row()
|
||||||
|
|
@ -418,6 +419,9 @@ class control_logic(design.design):
|
||||||
row += 1
|
row += 1
|
||||||
self.place_pen_row(row)
|
self.place_pen_row(row)
|
||||||
row += 1
|
row += 1
|
||||||
|
if (self.port_type == "rw") or (self.port_type == "w"):
|
||||||
|
self.place_rbl_delay_row(row)
|
||||||
|
row += 1
|
||||||
if (self.port_type == "rw") or (self.port_type == "r"):
|
if (self.port_type == "rw") or (self.port_type == "r"):
|
||||||
self.place_sen_row(row)
|
self.place_sen_row(row)
|
||||||
row += 1
|
row += 1
|
||||||
|
|
@ -442,6 +446,7 @@ class control_logic(design.design):
|
||||||
self.route_dffs()
|
self.route_dffs()
|
||||||
self.route_wlen()
|
self.route_wlen()
|
||||||
if (self.port_type == "rw") or (self.port_type == "w"):
|
if (self.port_type == "rw") or (self.port_type == "w"):
|
||||||
|
self.route_rbl_delay()
|
||||||
self.route_wen()
|
self.route_wen()
|
||||||
if (self.port_type == "rw") or (self.port_type == "r"):
|
if (self.port_type == "rw") or (self.port_type == "r"):
|
||||||
self.route_sen()
|
self.route_sen()
|
||||||
|
|
@ -470,6 +475,17 @@ class control_logic(design.design):
|
||||||
|
|
||||||
def route_delay(self):
|
def route_delay(self):
|
||||||
|
|
||||||
|
out_pos = self.delay_inst.get_pin("out").bc()
|
||||||
|
# Connect to the rail level with the vdd rail
|
||||||
|
# Use pen since it is in every type of control logic
|
||||||
|
vdd_ypos = self.p_en_bar_nand_inst.get_pin("vdd").by()
|
||||||
|
in_pos = vector(self.rail_offsets["rbl_bl_delay"].x,vdd_ypos)
|
||||||
|
mid1 = vector(out_pos.x,in_pos.y)
|
||||||
|
self.add_wire(("metal1","via1","metal2"),[out_pos, mid1, in_pos])
|
||||||
|
self.add_via_center(layers=("metal1","via1","metal2"),
|
||||||
|
offset=in_pos)
|
||||||
|
|
||||||
|
|
||||||
# Input from RBL goes to the delay line for futher delay
|
# Input from RBL goes to the delay line for futher delay
|
||||||
self.copy_layout_pin(self.delay_inst, "in", "rbl_bl")
|
self.copy_layout_pin(self.delay_inst, "in", "rbl_bl")
|
||||||
|
|
||||||
|
|
@ -481,12 +497,9 @@ class control_logic(design.design):
|
||||||
self.connect_inst(["clk","clk_buf","vdd","gnd"])
|
self.connect_inst(["clk","clk_buf","vdd","gnd"])
|
||||||
|
|
||||||
def place_clk_buf_row(self,row):
|
def place_clk_buf_row(self,row):
|
||||||
""" Place the multistage clock buffer below the control flops """
|
x_offset = self.control_x_offset
|
||||||
x_off = self.control_x_offset
|
|
||||||
(y_off,mirror)=self.get_offset(row)
|
|
||||||
|
|
||||||
offset = vector(x_off,y_off)
|
x_offset = self.place_util(self.clk_buf_inst, x_offset, row)
|
||||||
self.clk_buf_inst.place(offset, mirror)
|
|
||||||
|
|
||||||
self.row_end_inst.append(self.clk_buf_inst)
|
self.row_end_inst.append(self.clk_buf_inst)
|
||||||
|
|
||||||
|
|
@ -523,17 +536,10 @@ class control_logic(design.design):
|
||||||
self.connect_inst(["cs","clk_bar","gated_clk_bar","vdd","gnd"])
|
self.connect_inst(["cs","clk_bar","gated_clk_bar","vdd","gnd"])
|
||||||
|
|
||||||
def place_gated_clk_bar_row(self,row):
|
def place_gated_clk_bar_row(self,row):
|
||||||
""" Place the gated clk logic below the control flops """
|
x_offset = self.control_x_offset
|
||||||
x_off = self.control_x_offset
|
|
||||||
(y_off,mirror)=self.get_offset(row)
|
|
||||||
|
|
||||||
offset = vector(x_off,y_off)
|
x_offset = self.place_util(self.clk_bar_inst, x_offset, row)
|
||||||
self.clk_bar_inst.place(offset, mirror)
|
x_offset = self.place_util(self.gated_clk_bar_inst, x_offset, row)
|
||||||
|
|
||||||
x_off += self.inv.width
|
|
||||||
|
|
||||||
offset = vector(x_off,y_off)
|
|
||||||
self.gated_clk_bar_inst.place(offset, mirror)
|
|
||||||
|
|
||||||
self.row_end_inst.append(self.gated_clk_bar_inst)
|
self.row_end_inst.append(self.gated_clk_bar_inst)
|
||||||
|
|
||||||
|
|
@ -567,12 +573,9 @@ class control_logic(design.design):
|
||||||
self.connect_inst(["clk_buf", "cs","gated_clk_buf","vdd","gnd"])
|
self.connect_inst(["clk_buf", "cs","gated_clk_buf","vdd","gnd"])
|
||||||
|
|
||||||
def place_gated_clk_buf_row(self,row):
|
def place_gated_clk_buf_row(self,row):
|
||||||
""" Place the gated clk logic below the control flops """
|
x_offset = self.control_x_offset
|
||||||
x_off = self.control_x_offset
|
|
||||||
(y_off,mirror)=self.get_offset(row)
|
|
||||||
|
|
||||||
offset = vector(x_off,y_off)
|
x_offset = self.place_util(self.gated_clk_buf_inst, x_offset, row)
|
||||||
self.gated_clk_buf_inst.place(offset, mirror)
|
|
||||||
|
|
||||||
self.row_end_inst.append(self.gated_clk_buf_inst)
|
self.row_end_inst.append(self.gated_clk_buf_inst)
|
||||||
|
|
||||||
|
|
@ -594,11 +597,9 @@ class control_logic(design.design):
|
||||||
self.connect_inst(["gated_clk_bar", "wl_en", "vdd", "gnd"])
|
self.connect_inst(["gated_clk_bar", "wl_en", "vdd", "gnd"])
|
||||||
|
|
||||||
def place_wlen_row(self, row):
|
def place_wlen_row(self, row):
|
||||||
x_off = self.control_x_offset
|
x_offset = self.control_x_offset
|
||||||
(y_off,mirror)=self.get_offset(row)
|
|
||||||
|
|
||||||
offset = vector(x_off, y_off)
|
x_offset = self.place_util(self.wl_en_inst, x_offset, row)
|
||||||
self.wl_en_inst.place(offset, mirror)
|
|
||||||
|
|
||||||
self.row_end_inst.append(self.wl_en_inst)
|
self.row_end_inst.append(self.wl_en_inst)
|
||||||
|
|
||||||
|
|
@ -609,29 +610,32 @@ class control_logic(design.design):
|
||||||
self.connect_output(self.wl_en_inst, "Z", "wl_en")
|
self.connect_output(self.wl_en_inst, "Z", "wl_en")
|
||||||
|
|
||||||
def create_pen_row(self):
|
def create_pen_row(self):
|
||||||
self.p_en_bar_inst=self.add_inst(name="nand_p_en_bar",
|
self.p_en_bar_nand_inst=self.add_inst(name="nand_p_en_bar",
|
||||||
mod=self.nand2)
|
mod=self.nand2)
|
||||||
self.connect_inst(["gated_clk_buf", "rbl_bl_delay", "p_en_bar_unbuf", "vdd", "gnd"])
|
self.connect_inst(["gated_clk_buf", "rbl_bl_delay", "p_en_bar_unbuf", "vdd", "gnd"])
|
||||||
|
|
||||||
self.p_en_bar_inst=self.add_inst(name="buf_p_en_bar",
|
self.p_en_bar_driver_inst=self.add_inst(name="buf_p_en_bar",
|
||||||
mod=self.p_en_bar_driver)
|
mod=self.p_en_bar_driver)
|
||||||
self.connect_inst(["p_en_bar_unbuf", "p_en_bar", "vdd", "gnd"])
|
self.connect_inst(["p_en_bar_unbuf", "p_en_bar", "vdd", "gnd"])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def place_pen_row(self,row):
|
def place_pen_row(self,row):
|
||||||
x_off = self.control_x_offset
|
x_offset = self.control_x_offset
|
||||||
(y_off,mirror)=self.get_offset(row)
|
|
||||||
offset = vector(x_off,y_off)
|
|
||||||
self.p_en_bar_inst.place(offset, mirror)
|
|
||||||
|
|
||||||
self.row_end_inst.append(self.p_en_bar_inst)
|
x_offset = self.place_util(self.p_en_bar_nand_inst, x_offset, row)
|
||||||
|
x_offset = self.place_util(self.p_en_bar_driver_inst, x_offset, row)
|
||||||
|
|
||||||
|
self.row_end_inst.append(self.p_en_bar_driver_inst)
|
||||||
|
|
||||||
def route_pen(self):
|
def route_pen(self):
|
||||||
in_map = zip(["A"], ["gated_clk_buf"])
|
in_map = zip(["A", "B"], ["gated_clk_buf", "rbl_bl_delay"])
|
||||||
self.connect_vertical_bus(in_map, self.p_en_bar_inst, self.rail_offsets)
|
self.connect_vertical_bus(in_map, self.p_en_bar_nand_inst, self.rail_offsets)
|
||||||
|
|
||||||
self.connect_output(self.p_en_bar_inst, "Z", "p_en_bar")
|
out_pos = self.p_en_bar_nand_inst.get_pin("Z").rc()
|
||||||
|
in_pos = self.p_en_bar_driver_inst.get_pin("A").lc()
|
||||||
|
mid1 = vector(out_pos.x,in_pos.y)
|
||||||
|
self.add_wire(("metal1","via1","metal2"),[out_pos, mid1,in_pos])
|
||||||
|
|
||||||
|
self.connect_output(self.p_en_bar_driver_inst, "Z", "p_en_bar")
|
||||||
|
|
||||||
def create_sen_row(self):
|
def create_sen_row(self):
|
||||||
""" Create the sense enable buffer. """
|
""" Create the sense enable buffer. """
|
||||||
|
|
@ -646,15 +650,9 @@ class control_logic(design.design):
|
||||||
|
|
||||||
|
|
||||||
def place_sen_row(self,row):
|
def place_sen_row(self,row):
|
||||||
"""
|
x_offset = self.control_x_offset
|
||||||
The sense enable buffer gets placed to the far right of the
|
|
||||||
row.
|
|
||||||
"""
|
|
||||||
x_off = self.control_x_offset
|
|
||||||
(y_off,mirror)=self.get_offset(row)
|
|
||||||
|
|
||||||
offset = vector(x_off, y_off)
|
x_offset = self.place_util(self.s_en_gate_inst, x_offset, row)
|
||||||
self.s_en_gate_inst.place(offset, mirror)
|
|
||||||
|
|
||||||
self.row_end_inst.append(self.s_en_gate_inst)
|
self.row_end_inst.append(self.s_en_gate_inst)
|
||||||
|
|
||||||
|
|
@ -666,23 +664,41 @@ class control_logic(design.design):
|
||||||
else:
|
else:
|
||||||
input_name = "cs_bar"
|
input_name = "cs_bar"
|
||||||
|
|
||||||
sen_map = zip(["B"], [input_name])
|
sen_map = zip(["A", "B"], ["rbl_bl_delay", input_name])
|
||||||
self.connect_vertical_bus(sen_map, self.s_en_gate_inst, self.rail_offsets)
|
self.connect_vertical_bus(sen_map, self.s_en_gate_inst, self.rail_offsets)
|
||||||
|
|
||||||
out_pos = self.delay_inst.get_pin("out").bc()
|
|
||||||
in_pos = self.s_en_gate_inst.get_pin("A").lc()
|
|
||||||
mid1 = vector(out_pos.x,in_pos.y)
|
|
||||||
self.add_wire(("metal1","via1","metal2"),[out_pos, mid1,in_pos])
|
|
||||||
|
|
||||||
self.connect_output(self.s_en_gate_inst, "Z", "s_en")
|
self.connect_output(self.s_en_gate_inst, "Z", "s_en")
|
||||||
|
|
||||||
|
|
||||||
def create_wen_row(self):
|
def create_rbl_delay_row(self):
|
||||||
|
|
||||||
self.rbl_bl_delay_inv_inst = self.add_inst(name="rbl_bl_delay_inv",
|
self.rbl_bl_delay_inv_inst = self.add_inst(name="rbl_bl_delay_inv",
|
||||||
mod=self.inv)
|
mod=self.inv)
|
||||||
self.connect_inst(["rbl_bl_delay", "rbl_bl_delay_bar", "vdd", "gnd"])
|
self.connect_inst(["rbl_bl_delay", "rbl_bl_delay_bar", "vdd", "gnd"])
|
||||||
|
|
||||||
|
def place_rbl_delay_row(self,row):
|
||||||
|
x_offset = self.control_x_offset
|
||||||
|
|
||||||
|
x_offset = self.place_util(self.rbl_bl_delay_inv_inst, x_offset, row)
|
||||||
|
|
||||||
|
self.row_end_inst.append(self.rbl_bl_delay_inv_inst)
|
||||||
|
|
||||||
|
def route_rbl_delay(self):
|
||||||
|
# Connect from delay line
|
||||||
|
# Connect to rail
|
||||||
|
|
||||||
|
rbl_map = zip(["Z"], ["rbl_bl_delay_bar"])
|
||||||
|
self.connect_vertical_bus(rbl_map, self.rbl_bl_delay_inv_inst, self.rail_offsets, ("metal3", "via2", "metal2"))
|
||||||
|
# The pin is on M1, so we need another via as well
|
||||||
|
self.add_via_center(layers=("metal1","via1","metal2"),
|
||||||
|
offset=self.rbl_bl_delay_inv_inst.get_pin("Z").center())
|
||||||
|
|
||||||
|
|
||||||
|
rbl_map = zip(["A"], ["rbl_bl_delay"])
|
||||||
|
self.connect_vertical_bus(rbl_map, self.rbl_bl_delay_inv_inst, self.rail_offsets)
|
||||||
|
|
||||||
|
def create_wen_row(self):
|
||||||
|
|
||||||
# input: we (or cs) output: w_en
|
# input: we (or cs) output: w_en
|
||||||
if self.port_type == "rw":
|
if self.port_type == "rw":
|
||||||
input_name = "we"
|
input_name = "we"
|
||||||
|
|
@ -697,11 +713,9 @@ class control_logic(design.design):
|
||||||
|
|
||||||
|
|
||||||
def place_wen_row(self,row):
|
def place_wen_row(self,row):
|
||||||
x_off = self.ctrl_dff_inst.width + self.internal_bus_width
|
x_offset = self.control_x_offset
|
||||||
(y_off,mirror)=self.get_offset(row)
|
|
||||||
|
|
||||||
offset = vector(x_off, y_off)
|
x_offset = self.place_util(self.w_en_gate_inst, x_offset, row)
|
||||||
self.w_en_gate_inst.place(offset, mirror)
|
|
||||||
|
|
||||||
self.row_end_inst.append(self.w_en_gate_inst)
|
self.row_end_inst.append(self.w_en_gate_inst)
|
||||||
|
|
||||||
|
|
@ -712,7 +726,7 @@ class control_logic(design.design):
|
||||||
# No we for write-only reports, so use cs
|
# No we for write-only reports, so use cs
|
||||||
input_name = "cs"
|
input_name = "cs"
|
||||||
|
|
||||||
wen_map = zip(["A", "B"], [input_name, "gated_clk_bar"])
|
wen_map = zip(["A", "B", "C"], [input_name, "rbl_bl_delay_bar", "gated_clk_bar"])
|
||||||
self.connect_vertical_bus(wen_map, self.w_en_gate_inst, self.rail_offsets)
|
self.connect_vertical_bus(wen_map, self.w_en_gate_inst, self.rail_offsets)
|
||||||
|
|
||||||
self.connect_output(self.w_en_gate_inst, "Z", "w_en")
|
self.connect_output(self.w_en_gate_inst, "Z", "w_en")
|
||||||
|
|
@ -791,9 +805,8 @@ class control_logic(design.design):
|
||||||
self.add_power_pin("gnd", pin_loc)
|
self.add_power_pin("gnd", pin_loc)
|
||||||
self.add_path("metal1", [row_loc, pin_loc])
|
self.add_path("metal1", [row_loc, pin_loc])
|
||||||
|
|
||||||
if (self.port_type == "rw") or (self.port_type == "r"):
|
self.copy_layout_pin(self.delay_inst,"gnd")
|
||||||
self.copy_layout_pin(self.delay_inst,"gnd")
|
self.copy_layout_pin(self.delay_inst,"vdd")
|
||||||
self.copy_layout_pin(self.delay_inst,"vdd")
|
|
||||||
|
|
||||||
self.copy_layout_pin(self.ctrl_dff_inst,"gnd")
|
self.copy_layout_pin(self.ctrl_dff_inst,"gnd")
|
||||||
self.copy_layout_pin(self.ctrl_dff_inst,"vdd")
|
self.copy_layout_pin(self.ctrl_dff_inst,"vdd")
|
||||||
|
|
@ -958,3 +971,11 @@ class control_logic(design.design):
|
||||||
self.graph_inst_exclude.add(self.ctrl_dff_inst)
|
self.graph_inst_exclude.add(self.ctrl_dff_inst)
|
||||||
if self.port_type=="rw" or self.port_type=="w":
|
if self.port_type=="rw" or self.port_type=="w":
|
||||||
self.graph_inst_exclude.add(self.w_en_gate_inst)
|
self.graph_inst_exclude.add(self.w_en_gate_inst)
|
||||||
|
|
||||||
|
def place_util(self, inst, x_offset, row):
|
||||||
|
""" Utility to place a row and compute the next offset """
|
||||||
|
|
||||||
|
(y_offset,mirror)=self.get_offset(row)
|
||||||
|
offset = vector(x_offset, y_offset)
|
||||||
|
inst.place(offset, mirror)
|
||||||
|
return x_offset+inst.width
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue