mirror of https://github.com/VLSIDA/OpenRAM.git
Altering control logic for multiport. Netlist changes only.
This commit is contained in:
parent
bfc855b8b1
commit
7dfd37f79c
|
|
@ -24,6 +24,8 @@ class control_logic(design.design):
|
||||||
debug.info(1, "Creating {}".format(self.name))
|
debug.info(1, "Creating {}".format(self.name))
|
||||||
|
|
||||||
self.num_rows = num_rows
|
self.num_rows = num_rows
|
||||||
|
self.total_write = OPTS.num_rw_ports + OPTS.num_w_ports
|
||||||
|
self.total_read = OPTS.num_rw_ports + OPTS.num_r_ports
|
||||||
|
|
||||||
self.create_netlist()
|
self.create_netlist()
|
||||||
if not OPTS.netlist_only:
|
if not OPTS.netlist_only:
|
||||||
|
|
@ -61,7 +63,7 @@ class control_logic(design.design):
|
||||||
dff = dff_inv()
|
dff = dff_inv()
|
||||||
dff_height = dff.height
|
dff_height = dff.height
|
||||||
|
|
||||||
self.ctrl_dff_array = dff_inv_array(rows=2,columns=1)
|
self.ctrl_dff_array = dff_inv_array(rows=1+self.total_write,columns=1)
|
||||||
self.add_mod(self.ctrl_dff_array)
|
self.add_mod(self.ctrl_dff_array)
|
||||||
|
|
||||||
self.nand2 = pnand2(height=dff_height)
|
self.nand2 = pnand2(height=dff_height)
|
||||||
|
|
@ -96,14 +98,27 @@ class control_logic(design.design):
|
||||||
""" Setup bus names, determine the size of the busses etc """
|
""" Setup bus names, determine the size of the busses etc """
|
||||||
|
|
||||||
# List of input control signals
|
# List of input control signals
|
||||||
self.input_list =["csb","web0"]
|
self.input_list =["csb"]
|
||||||
self.dff_output_list =["cs_bar", "cs", "we_bar", "we"]
|
for port in range(self.total_write):
|
||||||
|
self.input_list.append("web{}".format(port))
|
||||||
|
|
||||||
|
self.dff_output_list =["cs_bar", "cs"]
|
||||||
|
for port in range(self.total_write):
|
||||||
|
self.dff_output_list.append("we_bar{}".format(port))
|
||||||
|
self.dff_output_list.append("we{}".format(port))
|
||||||
|
|
||||||
# list of output control signals (for making a vertical bus)
|
# list of output control signals (for making a vertical bus)
|
||||||
self.internal_bus_list = ["clk_buf", "clk_buf_bar", "we", "cs"]
|
self.internal_bus_list = ["clk_buf", "clk_buf_bar", "we", "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
|
||||||
|
|
||||||
# Outputs to the bank
|
# Outputs to the bank
|
||||||
self.output_list = ["s_en0", "w_en0", "clk_buf_bar", "clk_buf"]
|
self.output_list = ["s_en0"]
|
||||||
|
for port in range(self.total_write):
|
||||||
|
self.output_list.append("w_en{}".format(port))
|
||||||
|
self.output_list.append("clk_buf_bar")
|
||||||
|
self.output_list.append("clk_buf")
|
||||||
|
|
||||||
self.supply_list = ["vdd", "gnd"]
|
self.supply_list = ["vdd", "gnd"]
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -302,23 +317,31 @@ class control_logic(design.design):
|
||||||
|
|
||||||
def create_we_row(self):
|
def create_we_row(self):
|
||||||
# input: WE, CS output: w_en_bar
|
# input: WE, CS output: w_en_bar
|
||||||
self.w_en_bar_inst=self.add_inst(name="nand3_w_en_bar",
|
self.w_en_bar_inst = []
|
||||||
mod=self.nand3)
|
for port in range(self.total_write):
|
||||||
self.connect_inst(["clk_buf_bar", "cs", "we", "w_en_bar", "vdd", "gnd"])
|
self.w_en_bar_inst.append(self.add_inst(name="nand3_w_en_bar{}".format(port),
|
||||||
|
mod=self.nand3))
|
||||||
|
self.connect_inst(["clk_buf_bar", "cs", "we{}".format(port), "w_en_bar{}".format(port), "vdd", "gnd"])
|
||||||
|
|
||||||
# input: w_en_bar, output: pre_w_en
|
# input: w_en_bar, output: pre_w_en
|
||||||
self.pre_w_en_inst=self.add_inst(name="inv_pre_w_en",
|
self.pre_w_en_inst = []
|
||||||
mod=self.inv1)
|
for port in range(self.total_write):
|
||||||
self.connect_inst(["w_en_bar", "pre_w_en", "vdd", "gnd"])
|
self.pre_w_en_inst.append(self.add_inst(name="inv_pre_w_en{}".format(port),
|
||||||
|
mod=self.inv1))
|
||||||
|
self.connect_inst(["w_en_bar{}".format(port), "pre_w_en{}".format(port), "vdd", "gnd"])
|
||||||
|
|
||||||
# BUFFER INVERTERS FOR W_EN
|
# BUFFER INVERTERS FOR W_EN
|
||||||
self.pre_w_en_bar_inst=self.add_inst(name="inv_pre_w_en_bar",
|
self.pre_w_en_bar_inst = []
|
||||||
mod=self.inv2)
|
for port in range(self.total_write):
|
||||||
self.connect_inst(["pre_w_en", "pre_w_en_bar", "vdd", "gnd"])
|
self.pre_w_en_bar_inst.append(self.add_inst(name="inv_pre_w_en_bar{}".format(port),
|
||||||
|
mod=self.inv2))
|
||||||
|
self.connect_inst(["pre_w_en{}".format(port), "pre_w_en_bar{}".format(port), "vdd", "gnd"])
|
||||||
|
|
||||||
self.w_en_inst=self.add_inst(name="inv_w_en2",
|
self.w_en_inst = []
|
||||||
mod=self.inv8)
|
for port in range(self.total_write):
|
||||||
self.connect_inst(["pre_w_en_bar", "w_en0", "vdd", "gnd"])
|
self.w_en_inst.append(self.add_inst(name="inv_w_en2_{}".format(port),
|
||||||
|
mod=self.inv8))
|
||||||
|
self.connect_inst(["pre_w_en_bar{}".format(port), "w_en{}".format(port), "vdd", "gnd"])
|
||||||
|
|
||||||
|
|
||||||
def place_we_row(self,row):
|
def place_we_row(self,row):
|
||||||
|
|
@ -326,26 +349,26 @@ class control_logic(design.design):
|
||||||
(y_off,mirror)=self.get_offset(row)
|
(y_off,mirror)=self.get_offset(row)
|
||||||
|
|
||||||
w_en_bar_offset = vector(x_off, y_off)
|
w_en_bar_offset = vector(x_off, y_off)
|
||||||
self.w_en_bar_inst.place(offset=w_en_bar_offset,
|
self.w_en_bar_inst[0].place(offset=w_en_bar_offset,
|
||||||
mirror=mirror)
|
mirror=mirror)
|
||||||
x_off += self.nand3.width
|
x_off += self.nand3.width
|
||||||
|
|
||||||
pre_w_en_offset = vector(x_off, y_off)
|
pre_w_en_offset = vector(x_off, y_off)
|
||||||
self.pre_w_en_inst.place(offset=pre_w_en_offset,
|
self.pre_w_en_inst[0].place(offset=pre_w_en_offset,
|
||||||
mirror=mirror)
|
mirror=mirror)
|
||||||
x_off += self.inv1.width
|
x_off += self.inv1.width
|
||||||
|
|
||||||
pre_w_en_bar_offset = vector(x_off, y_off)
|
pre_w_en_bar_offset = vector(x_off, y_off)
|
||||||
self.pre_w_en_bar_inst.place(offset=pre_w_en_bar_offset,
|
self.pre_w_en_bar_inst[0].place(offset=pre_w_en_bar_offset,
|
||||||
mirror=mirror)
|
mirror=mirror)
|
||||||
x_off += self.inv2.width
|
x_off += self.inv2.width
|
||||||
|
|
||||||
w_en_offset = vector(x_off, y_off)
|
w_en_offset = vector(x_off, y_off)
|
||||||
self.w_en_inst.place(offset=w_en_offset,
|
self.w_en_inst[0].place(offset=w_en_offset,
|
||||||
mirror=mirror)
|
mirror=mirror)
|
||||||
x_off += self.inv8.width
|
x_off += self.inv8.width
|
||||||
|
|
||||||
self.row_end_inst.append(self.w_en_inst)
|
self.row_end_inst.append(self.w_en_inst[0])
|
||||||
|
|
||||||
|
|
||||||
def route_rbl_in(self):
|
def route_rbl_in(self):
|
||||||
|
|
@ -423,19 +446,19 @@ class control_logic(design.design):
|
||||||
|
|
||||||
def route_wen(self):
|
def route_wen(self):
|
||||||
wen_map = zip(["A", "B", "C"], ["clk_buf_bar", "cs", "we"])
|
wen_map = zip(["A", "B", "C"], ["clk_buf_bar", "cs", "we"])
|
||||||
self.connect_vertical_bus(wen_map, self.w_en_bar_inst, self.rail_offsets)
|
self.connect_vertical_bus(wen_map, self.w_en_bar_inst[0], self.rail_offsets)
|
||||||
|
|
||||||
# Connect the NAND3 output to the inverter
|
# Connect the NAND3 output to the inverter
|
||||||
# The pins are assumed to extend all the way to the cell edge
|
# The pins are assumed to extend all the way to the cell edge
|
||||||
w_en_bar_pos = self.w_en_bar_inst.get_pin("Z").center()
|
w_en_bar_pos = self.w_en_bar_inst[0].get_pin("Z").center()
|
||||||
inv_in_pos = self.pre_w_en_inst.get_pin("A").center()
|
inv_in_pos = self.pre_w_en_inst[0].get_pin("A").center()
|
||||||
mid1 = vector(inv_in_pos.x,w_en_bar_pos.y)
|
mid1 = vector(inv_in_pos.x,w_en_bar_pos.y)
|
||||||
self.add_path("metal1",[w_en_bar_pos,mid1,inv_in_pos])
|
self.add_path("metal1",[w_en_bar_pos,mid1,inv_in_pos])
|
||||||
|
|
||||||
self.add_path("metal1",[self.pre_w_en_inst.get_pin("Z").center(), self.pre_w_en_bar_inst.get_pin("A").center()])
|
self.add_path("metal1",[self.pre_w_en_inst[0].get_pin("Z").center(), self.pre_w_en_bar_inst[0].get_pin("A").center()])
|
||||||
self.add_path("metal1",[self.pre_w_en_bar_inst.get_pin("Z").center(), self.w_en_inst.get_pin("A").center()])
|
self.add_path("metal1",[self.pre_w_en_bar_inst[0].get_pin("Z").center(), self.w_en_inst[0].get_pin("A").center()])
|
||||||
|
|
||||||
self.connect_output(self.w_en_inst, "Z", "w_en0")
|
self.connect_output(self.w_en_inst[0], "Z", "w_en0")
|
||||||
|
|
||||||
def route_sen(self):
|
def route_sen(self):
|
||||||
rbl_out_pos = self.rbl_inst.get_pin("out").bc()
|
rbl_out_pos = self.rbl_inst.get_pin("out").bc()
|
||||||
|
|
|
||||||
|
|
@ -34,9 +34,7 @@ class sram_1bank(sram_base):
|
||||||
|
|
||||||
self.bank_inst=self.create_bank(0)
|
self.bank_inst=self.create_bank(0)
|
||||||
|
|
||||||
self.control_logic_inst = [None] * self.total_ports
|
self.control_logic_inst = self.create_control_logic()
|
||||||
for port in range(self.total_ports):
|
|
||||||
self.control_logic_inst[port] = self.create_control_logic(port)
|
|
||||||
|
|
||||||
self.row_addr_dff_inst = self.create_row_addr_dff()
|
self.row_addr_dff_inst = self.create_row_addr_dff()
|
||||||
|
|
||||||
|
|
@ -61,11 +59,11 @@ class sram_1bank(sram_base):
|
||||||
# up to the row address DFFs.
|
# up to the row address DFFs.
|
||||||
control_pos = vector(-self.control_logic.width - 2*self.m2_pitch,
|
control_pos = vector(-self.control_logic.width - 2*self.m2_pitch,
|
||||||
self.bank.bank_center.y - self.control_logic.control_logic_center.y)
|
self.bank.bank_center.y - self.control_logic.control_logic_center.y)
|
||||||
self.control_logic_inst[0].place(control_pos)
|
self.control_logic_inst.place(control_pos)
|
||||||
|
|
||||||
# The row address bits are placed above the control logic aligned on the right.
|
# The row address bits are placed above the control logic aligned on the right.
|
||||||
row_addr_pos = vector(self.control_logic_inst[0].rx() - self.row_addr_dff.width,
|
row_addr_pos = vector(self.control_logic_inst.rx() - self.row_addr_dff.width,
|
||||||
self.control_logic_inst[0].uy())
|
self.control_logic_inst.uy())
|
||||||
self.row_addr_dff_inst.place(row_addr_pos)
|
self.row_addr_dff_inst.place(row_addr_pos)
|
||||||
|
|
||||||
# This is M2 pitch even though it is on M1 to help stem via spacings on the trunk
|
# This is M2 pitch even though it is on M1 to help stem via spacings on the trunk
|
||||||
|
|
@ -97,7 +95,7 @@ class sram_1bank(sram_base):
|
||||||
"""
|
"""
|
||||||
# Connect the control pins as inputs
|
# Connect the control pins as inputs
|
||||||
for n in self.control_logic_inputs + ["clk"]:
|
for n in self.control_logic_inputs + ["clk"]:
|
||||||
self.copy_layout_pin(self.control_logic_inst[0], n)
|
self.copy_layout_pin(self.control_logic_inst, n)
|
||||||
|
|
||||||
for i in range(self.word_size):
|
for i in range(self.word_size):
|
||||||
dout_name = "dout0[{}]".format(i)
|
dout_name = "dout0[{}]".format(i)
|
||||||
|
|
@ -136,7 +134,7 @@ class sram_1bank(sram_base):
|
||||||
""" Route the clock network """
|
""" Route the clock network """
|
||||||
|
|
||||||
# This is the actual input to the SRAM
|
# This is the actual input to the SRAM
|
||||||
self.copy_layout_pin(self.control_logic_inst[0], "clk")
|
self.copy_layout_pin(self.control_logic_inst, "clk")
|
||||||
|
|
||||||
# Connect all of these clock pins to the clock in the central bus
|
# Connect all of these clock pins to the clock in the central bus
|
||||||
# This is something like a "spine" clock distribution. The two spines
|
# This is something like a "spine" clock distribution. The two spines
|
||||||
|
|
@ -160,7 +158,7 @@ class sram_1bank(sram_base):
|
||||||
|
|
||||||
# This uses a metal2 track to the right of the control/row addr DFF
|
# This uses a metal2 track to the right of the control/row addr DFF
|
||||||
# to route vertically.
|
# to route vertically.
|
||||||
control_clk_buf_pin = self.control_logic_inst[0].get_pin("clk_buf")
|
control_clk_buf_pin = self.control_logic_inst.get_pin("clk_buf")
|
||||||
control_clk_buf_pos = control_clk_buf_pin.rc()
|
control_clk_buf_pos = control_clk_buf_pin.rc()
|
||||||
row_addr_clk_pin = self.row_addr_dff_inst.get_pin("clk")
|
row_addr_clk_pin = self.row_addr_dff_inst.get_pin("clk")
|
||||||
row_addr_clk_pos = row_addr_clk_pin.rc()
|
row_addr_clk_pos = row_addr_clk_pin.rc()
|
||||||
|
|
@ -179,7 +177,7 @@ class sram_1bank(sram_base):
|
||||||
top_instances = [self.bank_inst,
|
top_instances = [self.bank_inst,
|
||||||
self.row_addr_dff_inst,
|
self.row_addr_dff_inst,
|
||||||
self.data_dff_inst,
|
self.data_dff_inst,
|
||||||
self.control_logic_inst[0]]
|
self.control_logic_inst]
|
||||||
if self.col_addr_dff:
|
if self.col_addr_dff:
|
||||||
top_instances.append(self.col_addr_dff_inst)
|
top_instances.append(self.col_addr_dff_inst)
|
||||||
|
|
||||||
|
|
@ -195,7 +193,7 @@ class sram_1bank(sram_base):
|
||||||
top_instances = [self.bank_inst,
|
top_instances = [self.bank_inst,
|
||||||
self.row_addr_dff_inst,
|
self.row_addr_dff_inst,
|
||||||
self.data_dff_inst,
|
self.data_dff_inst,
|
||||||
self.control_logic_inst[0]]
|
self.control_logic_inst]
|
||||||
if self.col_addr_dff:
|
if self.col_addr_dff:
|
||||||
top_instances.append(self.col_addr_dff_inst)
|
top_instances.append(self.col_addr_dff_inst)
|
||||||
|
|
||||||
|
|
@ -269,7 +267,7 @@ class sram_1bank(sram_base):
|
||||||
def route_control_logic(self):
|
def route_control_logic(self):
|
||||||
""" Route the outputs from the control logic module """
|
""" Route the outputs from the control logic module """
|
||||||
for n in self.control_logic_outputs:
|
for n in self.control_logic_outputs:
|
||||||
src_pin = self.control_logic_inst[0].get_pin(n)
|
src_pin = self.control_logic_inst.get_pin(n)
|
||||||
dest_pin = self.bank_inst.get_pin(n)
|
dest_pin = self.bank_inst.get_pin(n)
|
||||||
self.connect_rail_from_left_m2m3(src_pin, dest_pin)
|
self.connect_rail_from_left_m2m3(src_pin, dest_pin)
|
||||||
self.add_via_center(layers=("metal1","via1","metal2"),
|
self.add_via_center(layers=("metal1","via1","metal2"),
|
||||||
|
|
@ -336,7 +334,7 @@ class sram_1bank(sram_base):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
for n in self.control_logic_outputs:
|
for n in self.control_logic_outputs:
|
||||||
pin = self.control_logic_inst[0].get_pin(n)
|
pin = self.control_logic_inst.get_pin(n)
|
||||||
self.add_label(text=n,
|
self.add_label(text=n,
|
||||||
layer=pin.layer,
|
layer=pin.layer,
|
||||||
offset=pin.center())
|
offset=pin.center())
|
||||||
|
|
|
||||||
|
|
@ -375,14 +375,19 @@ class sram_base(design):
|
||||||
self.connect_inst(inputs + outputs + ["clk_buf", "vdd", "gnd"])
|
self.connect_inst(inputs + outputs + ["clk_buf", "vdd", "gnd"])
|
||||||
return inst
|
return inst
|
||||||
|
|
||||||
def create_control_logic(self, port):
|
def create_control_logic(self):
|
||||||
""" Add and place control logic """
|
""" Add and place control logic """
|
||||||
inst = self.add_inst(name="control",
|
inst = self.add_inst(name="control",
|
||||||
mod=self.control_logic)
|
mod=self.control_logic)
|
||||||
|
|
||||||
self.connect_inst(["csb", "web{}".format(port), "clk",
|
temp = ["csb"]
|
||||||
"s_en{}".format(port), "w_en{}".format(port), "clk_buf_bar", "clk_buf",
|
for port in range(self.total_write):
|
||||||
"vdd", "gnd"])
|
temp.append("web{}".format(port))
|
||||||
|
temp.extend(["clk", "s_en0"])
|
||||||
|
for port in range(self.total_write):
|
||||||
|
temp.append("w_en{}".format(port))
|
||||||
|
temp.extend(["clk_buf_bar", "clk_buf", "vdd", "gnd"])
|
||||||
|
self.connect_inst(temp)
|
||||||
|
|
||||||
#self.connect_inst(self.control_logic_inputs + self.control_logic_outputs + ["vdd", "gnd"])
|
#self.connect_inst(self.control_logic_inputs + self.control_logic_outputs + ["vdd", "gnd"])
|
||||||
return inst
|
return inst
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue