mirror of https://github.com/VLSIDA/OpenRAM.git
Control logic route changes.
Move wl_en to top control signal. Route wl_en directly to port_address. Reorder input bus to bank.
This commit is contained in:
parent
e144f03b23
commit
4a40e96f6d
|
|
@ -329,13 +329,13 @@ class bank(design.design):
|
||||||
self.input_control_signals = []
|
self.input_control_signals = []
|
||||||
port_num = 0
|
port_num = 0
|
||||||
for port in range(OPTS.num_rw_ports):
|
for port in range(OPTS.num_rw_ports):
|
||||||
self.input_control_signals.append(["s_en{}".format(port_num), "w_en{}".format(port_num), "p_en_bar{}".format(port_num), "wl_en{}".format(port_num)])
|
self.input_control_signals.append(["p_en_bar{}".format(port_num), "s_en{}".format(port_num), "w_en{}".format(port_num)])
|
||||||
port_num += 1
|
port_num += 1
|
||||||
for port in range(OPTS.num_w_ports):
|
for port in range(OPTS.num_w_ports):
|
||||||
self.input_control_signals.append(["w_en{}".format(port_num), "p_en_bar{}".format(port_num), "wl_en{}".format(port_num)])
|
self.input_control_signals.append(["p_en_bar{}".format(port_num), "w_en{}".format(port_num)])
|
||||||
port_num += 1
|
port_num += 1
|
||||||
for port in range(OPTS.num_r_ports):
|
for port in range(OPTS.num_r_ports):
|
||||||
self.input_control_signals.append(["s_en{}".format(port_num), "p_en_bar{}".format(port_num), "wl_en{}".format(port_num)])
|
self.input_control_signals.append(["p_en_bar{}".format(port_num), "s_en{}".format(port_num)])
|
||||||
port_num += 1
|
port_num += 1
|
||||||
|
|
||||||
# Number of control lines in the bus for each port
|
# Number of control lines in the bus for each port
|
||||||
|
|
@ -691,6 +691,8 @@ class bank(design.design):
|
||||||
make_pins=(self.num_banks==1),
|
make_pins=(self.num_banks==1),
|
||||||
pitch=self.m3_pitch)
|
pitch=self.m3_pitch)
|
||||||
|
|
||||||
|
self.copy_layout_pin(self.port_address_inst[0], "wl_en", self.prefix + "wl_en0")
|
||||||
|
|
||||||
# Port 1
|
# Port 1
|
||||||
if len(self.all_ports)==2:
|
if len(self.all_ports)==2:
|
||||||
# The other control bus is routed up to two pitches above the bitcell array
|
# The other control bus is routed up to two pitches above the bitcell array
|
||||||
|
|
@ -706,6 +708,8 @@ class bank(design.design):
|
||||||
make_pins=(self.num_banks==1),
|
make_pins=(self.num_banks==1),
|
||||||
pitch=self.m3_pitch)
|
pitch=self.m3_pitch)
|
||||||
|
|
||||||
|
self.copy_layout_pin(self.port_address_inst[1], "wl_en", self.prefix + "wl_en1")
|
||||||
|
|
||||||
def route_port_data_to_bitcell_array(self, port):
|
def route_port_data_to_bitcell_array(self, port):
|
||||||
""" Routing of BL and BR between port data and bitcell array """
|
""" Routing of BL and BR between port data and bitcell array """
|
||||||
|
|
||||||
|
|
@ -1054,21 +1058,6 @@ class bank(design.design):
|
||||||
to_layer="m2",
|
to_layer="m2",
|
||||||
offset=control_pos)
|
offset=control_pos)
|
||||||
|
|
||||||
# clk to wordline_driver
|
|
||||||
control_signal = self.prefix + "wl_en{}".format(port)
|
|
||||||
if port % 2:
|
|
||||||
pin_pos = self.port_address_inst[port].get_pin("wl_en").uc()
|
|
||||||
control_y_offset = self.bus_pins[port][control_signal].by()
|
|
||||||
mid_pos = vector(pin_pos.x, control_y_offset + self.m1_pitch)
|
|
||||||
else:
|
|
||||||
pin_pos = self.port_address_inst[port].get_pin("wl_en").bc()
|
|
||||||
control_y_offset = self.bus_pins[port][control_signal].uy()
|
|
||||||
mid_pos = vector(pin_pos.x, control_y_offset - self.m1_pitch)
|
|
||||||
control_x_offset = self.bus_pins[port][control_signal].cx()
|
|
||||||
control_pos = vector(control_x_offset, mid_pos.y)
|
|
||||||
self.add_wire(self.m1_stack, [pin_pos, mid_pos, control_pos])
|
|
||||||
self.add_via_center(layers=self.m1_stack,
|
|
||||||
offset=control_pos)
|
|
||||||
|
|
||||||
def graph_exclude_precharge(self):
|
def graph_exclude_precharge(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -333,8 +333,9 @@ class control_logic(design.design):
|
||||||
row += 1
|
row += 1
|
||||||
self.place_gated_clk_buf_row(row)
|
self.place_gated_clk_buf_row(row)
|
||||||
row += 1
|
row += 1
|
||||||
self.place_wlen_row(row)
|
if (self.port_type == "rw") or (self.port_type == "r"):
|
||||||
row += 1
|
self.place_sen_row(row)
|
||||||
|
row += 1
|
||||||
if (self.port_type == "rw") or (self.port_type == "w"):
|
if (self.port_type == "rw") or (self.port_type == "w"):
|
||||||
self.place_wen_row(row)
|
self.place_wen_row(row)
|
||||||
height = self.w_en_gate_inst.uy()
|
height = self.w_en_gate_inst.uy()
|
||||||
|
|
@ -345,9 +346,8 @@ class control_logic(design.design):
|
||||||
if (self.port_type == "rw") or (self.port_type == "w"):
|
if (self.port_type == "rw") or (self.port_type == "w"):
|
||||||
self.place_rbl_delay_row(row)
|
self.place_rbl_delay_row(row)
|
||||||
row += 1
|
row += 1
|
||||||
if (self.port_type == "rw") or (self.port_type == "r"):
|
self.place_wlen_row(row)
|
||||||
self.place_sen_row(row)
|
row += 1
|
||||||
row += 1
|
|
||||||
self.place_delay(row)
|
self.place_delay(row)
|
||||||
height = self.delay_inst.uy()
|
height = self.delay_inst.uy()
|
||||||
control_center_y = self.delay_inst.by()
|
control_center_y = self.delay_inst.by()
|
||||||
|
|
|
||||||
|
|
@ -340,6 +340,15 @@ class sram_1bank(sram_base):
|
||||||
|
|
||||||
def route_dff(self, port, add_routes):
|
def route_dff(self, port, add_routes):
|
||||||
|
|
||||||
|
# This is only done when we add_routes because the data channel will be larger
|
||||||
|
# so that can be used for area estimation.
|
||||||
|
if add_routes:
|
||||||
|
self.route_col_addr_dffs(port)
|
||||||
|
|
||||||
|
self.route_data_dffs(port, add_routes)
|
||||||
|
|
||||||
|
def route_col_addr_dffs(self, port):
|
||||||
|
|
||||||
route_map = []
|
route_map = []
|
||||||
|
|
||||||
# column mux dff is routed on it's own since it is to the far end
|
# column mux dff is routed on it's own since it is to the far end
|
||||||
|
|
@ -351,6 +360,38 @@ class sram_1bank(sram_base):
|
||||||
bank_pins = [self.bank_inst.get_pin(x) for x in bank_names]
|
bank_pins = [self.bank_inst.get_pin(x) for x in bank_names]
|
||||||
route_map.extend(list(zip(bank_pins, dff_pins)))
|
route_map.extend(list(zip(bank_pins, dff_pins)))
|
||||||
|
|
||||||
|
if len(route_map) > 0:
|
||||||
|
|
||||||
|
layer_stack = self.m1_stack
|
||||||
|
|
||||||
|
if port == 0:
|
||||||
|
offset = vector(self.control_logic_insts[port].rx() + self.dff.width,
|
||||||
|
- self.data_bus_size[port] + 2 * self.m3_pitch)
|
||||||
|
cr = channel_route(netlist=route_map,
|
||||||
|
offset=offset,
|
||||||
|
layer_stack=layer_stack,
|
||||||
|
parent=self)
|
||||||
|
# This causes problem in magic since it sometimes cannot extract connectivity of isntances
|
||||||
|
# with no active devices.
|
||||||
|
self.add_inst(cr.name, cr)
|
||||||
|
self.connect_inst([])
|
||||||
|
#self.add_flat_inst(cr.name, cr)
|
||||||
|
else:
|
||||||
|
offset = vector(0,
|
||||||
|
self.bank.height + self.m3_pitch)
|
||||||
|
cr = channel_route(netlist=route_map,
|
||||||
|
offset=offset,
|
||||||
|
layer_stack=layer_stack,
|
||||||
|
parent=self)
|
||||||
|
# This causes problem in magic since it sometimes cannot extract connectivity of isntances
|
||||||
|
# with no active devices.
|
||||||
|
self.add_inst(cr.name, cr)
|
||||||
|
self.connect_inst([])
|
||||||
|
#self.add_flat_inst(cr.name, cr)
|
||||||
|
|
||||||
|
def route_data_dffs(self, port, add_routes):
|
||||||
|
route_map = []
|
||||||
|
|
||||||
# wmask dff
|
# wmask dff
|
||||||
if self.num_wmasks > 0 and port in self.write_ports:
|
if self.num_wmasks > 0 and port in self.write_ports:
|
||||||
dff_names = ["dout_{}".format(x) for x in range(self.num_wmasks)]
|
dff_names = ["dout_{}".format(x) for x in range(self.num_wmasks)]
|
||||||
|
|
@ -377,6 +418,7 @@ class sram_1bank(sram_base):
|
||||||
|
|
||||||
if len(route_map) > 0:
|
if len(route_map) > 0:
|
||||||
|
|
||||||
|
# The write masks will have blockages on M1
|
||||||
if self.num_wmasks > 0 and port in self.write_ports:
|
if self.num_wmasks > 0 and port in self.write_ports:
|
||||||
layer_stack = self.m3_stack
|
layer_stack = self.m3_stack
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# See LICENSE for licensing information.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2016-2021 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
|
||||||
|
|
||||||
|
|
||||||
|
class sram_1bank_4mux_1rw_1r_test(openram_test):
|
||||||
|
|
||||||
|
def runTest(self):
|
||||||
|
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
|
||||||
|
globals.init_openram(config_file)
|
||||||
|
from sram_config import sram_config
|
||||||
|
|
||||||
|
OPTS.num_rw_ports = 1
|
||||||
|
OPTS.num_r_ports = 1
|
||||||
|
OPTS.num_w_ports = 0
|
||||||
|
globals.setup_bitcell()
|
||||||
|
|
||||||
|
c = sram_config(word_size=4,
|
||||||
|
num_words=64,
|
||||||
|
num_banks=1)
|
||||||
|
|
||||||
|
c.words_per_row=4
|
||||||
|
c.recompute_sizes()
|
||||||
|
debug.info(1, "Layout test for {}rw,{}r,{}w sram "
|
||||||
|
"with {} bit words, {} words, {} words per "
|
||||||
|
"row, {} banks".format(OPTS.num_rw_ports,
|
||||||
|
OPTS.num_r_ports,
|
||||||
|
OPTS.num_w_ports,
|
||||||
|
c.word_size,
|
||||||
|
c.num_words,
|
||||||
|
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())
|
||||||
Loading…
Reference in New Issue