make code clean

This commit is contained in:
FriedrichWu 2024-11-12 17:02:02 +01:00
parent 1f1f064036
commit f56460bb94
11 changed files with 196 additions and 7312 deletions

View File

@ -18,6 +18,7 @@ from openram.base import lef
from openram.sram_factory import factory from openram.sram_factory import factory
from openram.tech import spice from openram.tech import spice
from openram import OPTS, print_time from openram import OPTS, print_time
import re
class sram_1bank(design, verilog, lef): class sram_1bank(design, verilog, lef):
@ -207,7 +208,7 @@ class sram_1bank(design, verilog, lef):
if not OPTS.is_unit_test: if not OPTS.is_unit_test:
print_time("Submodules", datetime.datetime.now(), start_time) print_time("Submodules", datetime.datetime.now(), start_time)
def create_layout(self, position_add=0, mod=0): def create_layout(self, position_add=0, mod=0, route_option="classic"):
""" Layout creation """ """ Layout creation """
start_time = datetime.datetime.now() start_time = datetime.datetime.now()
self.place_instances_changeable(position_add=position_add) self.place_instances_changeable(position_add=position_add)
@ -215,7 +216,7 @@ class sram_1bank(design, verilog, lef):
print_time("Placement", datetime.datetime.now(), start_time) print_time("Placement", datetime.datetime.now(), start_time)
start_time = datetime.datetime.now() start_time = datetime.datetime.now()
self.route_layout(mod=mod) self.route_layout(mod=mod, route_option=route_option)
if not OPTS.is_unit_test: if not OPTS.is_unit_test:
print_time("Routing", datetime.datetime.now(), start_time) print_time("Routing", datetime.datetime.now(), start_time)
@ -319,7 +320,7 @@ class sram_1bank(design, verilog, lef):
# Grid is left with many top level pins # Grid is left with many top level pins
pass pass
def route_escape_pins(self, bbox=None, mod=0): def route_escape_pins(self, bbox=None, mod=0, route_option="classic"):
""" """
Add the top-level pins for a single bank SRAM with control. Add the top-level pins for a single bank SRAM with control.
""" """
@ -362,6 +363,7 @@ class sram_1bank(design, verilog, lef):
for bit in range(self.num_spare_cols): for bit in range(self.num_spare_cols):
pins_to_route.append("spare_wen{0}[{1}]".format(port, bit)) pins_to_route.append("spare_wen{0}[{1}]".format(port, bit))
if route_option == "classic":
from openram.router import signal_escape_router as router from openram.router import signal_escape_router as router
# mod Use for control which edge/position the pins(dout) will be placed # mod Use for control which edge/position the pins(dout) will be placed
# 0 -> default # 0 -> default
@ -372,6 +374,17 @@ class sram_1bank(design, verilog, lef):
design=self, design=self,
mod=mod) mod=mod)
rtr.route(pins_to_route) rtr.route(pins_to_route)
elif route_option == "fast":
# use io_pin_placer
# put the IO pins at the edge
from openram.router.io_pin_placer import io_pin_placer as placer
pl = placer(layers=self.m3_stack,
bbox=bbox,
design=self)
for name in pins_to_route:
debug.warning("pins_to_route pins -> {0}".format(name))
pl.add_io_pins_connected(pins_to_route)
#pl.add_io_pins(pins_to_route)
def compute_bus_sizes(self): def compute_bus_sizes(self):
""" Compute the independent bus widths shared between two and four bank SRAMs """ """ Compute the independent bus widths shared between two and four bank SRAMs """
@ -853,7 +866,6 @@ class sram_1bank(design, verilog, lef):
for port in self.all_ports: for port in self.all_ports:
# Add the extra position # Add the extra position
self.data_bus_size[port] += position_add self.data_bus_size[port] += position_add
# Re-place with the new channel size # Re-place with the new channel size
self.place_dffs() self.place_dffs()
@ -866,7 +878,7 @@ class sram_1bank(design, verilog, lef):
x_offset = self.control_logic_insts[port].rx() - self.row_addr_dff_insts[port].width x_offset = self.control_logic_insts[port].rx() - self.row_addr_dff_insts[port].width
# It is above the control logic and the predecoder array # It is above the control logic and the predecoder array
y_offset = max(self.control_logic_insts[port].uy(), self.bank.predecoder_top) y_offset = max(self.control_logic_insts[port].uy(), self.bank.predecoder_top)
y_offset = y_offset + 0.4 # fix, maigc number
self.row_addr_pos[port] = vector(x_offset, y_offset) self.row_addr_pos[port] = vector(x_offset, y_offset)
self.row_addr_dff_insts[port].place(self.row_addr_pos[port]) self.row_addr_dff_insts[port].place(self.row_addr_pos[port])
@ -875,7 +887,7 @@ class sram_1bank(design, verilog, lef):
# The row address bits are placed above the control logic aligned on the left. # The row address bits are placed above the control logic aligned on the left.
x_offset = self.control_pos[port].x - self.control_logic_insts[port].width + self.row_addr_dff_insts[port].width x_offset = self.control_pos[port].x - self.control_logic_insts[port].width + self.row_addr_dff_insts[port].width
# If it can be placed above the predecoder and below the control logic, do it # If it can be placed above the predecoder and below the control logic, do it
y_offset = self.bank.predecoder_bottom y_offset = min(self.control_logic_insts[port].by(), self.bank.predecoder_top)
self.row_addr_pos[port] = vector(x_offset, y_offset) self.row_addr_pos[port] = vector(x_offset, y_offset)
self.row_addr_dff_insts[port].place(self.row_addr_pos[port], mirror="XY") self.row_addr_dff_insts[port].place(self.row_addr_pos[port], mirror="XY")
@ -1061,7 +1073,7 @@ class sram_1bank(design, verilog, lef):
"spare_wen{0}[{1}]".format(port, bit), "spare_wen{0}[{1}]".format(port, bit),
start_layer=pin_layer) start_layer=pin_layer)
def route_layout(self, mod=0): def route_layout(self, mod=0, route_option="classic"):
""" Route a single bank SRAM """ """ Route a single bank SRAM """
self.route_clk() self.route_clk()
@ -1085,12 +1097,11 @@ class sram_1bank(design, verilog, lef):
if OPTS.perimeter_pins: if OPTS.perimeter_pins:
# We now route the escape routes far enough out so that they will # We now route the escape routes far enough out so that they will
# reach past the power ring or stripes on the sides # reach past the power ring or stripes on the sides
self.route_escape_pins(bbox=init_bbox, mod=mod) self.route_escape_pins(bbox=init_bbox, mod=mod, route_option=route_option)
if OPTS.route_supplies: if OPTS.route_supplies:
self.route_supplies(init_bbox) self.route_supplies(init_bbox)
def route_dffs(self, add_routes=True): def route_dffs(self, add_routes=True):
for port in self.all_ports: for port in self.all_ports:

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -218,108 +218,6 @@ class io_pin_placer(router):
debug.warning("pin added: {0}".format(fake_pin)) debug.warning("pin added: {0}".format(fake_pin))
def create_fake_pin(self, pin):
""" Create a fake pin on the perimeter orthogonal to the given pin. """
ll, ur = self.bbox
c = pin.center()
print("inside pin name")
print("----------------------------------------------------------")
print(pin.name)
# Find the closest edge
edge, vertical = self.get_closest_edge(c)
# Relocate the pin position of addr/dout
pattern_addr = r'^addr'
pattern_dout = r'^dout'
if re.match(pattern_addr, pin.name):# all the addr[] should be placed at vertical edge
if edge == "top" or edge == "left":
edge = "left"
vertical = True
elif edge == "bottom" or edge == "right":
edge = "right"
vertical = True
if re.match(pattern_dout, pin.name):# all the dout[] should be placed at horizontal edge
if edge == "bottom" or edge == "right":
edge = "bottom"
vertical = False
elif edge == "top" or edge == "left":
edge = "top"
vertical = False
offset = 0.95 + 0.19 # FIX: this is the magic number to overcome the ovetflow problem at the boundary, may need a method
add_distance = 0
# Keep the fake pin out of the SRAM layout are so that they won't be
# blocked by previous signals if they're on the same orthogonal line
if edge == "left":
fake_center = vector(ll.x - self.track_wire * 2 + offset, c.y)
is_too_close = any(abs(pin_added.center().y - fake_center.y) < (0.4 + self.half_wire * 4)for pin_added in self.io_pins_added_left)
while is_too_close:
debug.warning("overlap, changing position")
add_distance = add_distance + 0.1#+ 0.4 + self.half_wire * 4
fake_center = vector(ll.x - self.track_wire * 2 + offset, c.y + add_distance)
is_too_close = any(abs(pin_added.center().y - fake_center.y) < (0.4 + self.half_wire * 4)for pin_added in self.io_pins_added_left)
if edge == "bottom":
fake_center = vector(c.x, ll.y - self.track_wire * 2 + offset)
is_too_close = any(abs(pin_added.center().x - fake_center.x) < (0.4 + self.half_wire * 4)for pin_added in self.io_pins_added_down)
while is_too_close:
debug.warning("overlap, changing position")
add_distance = add_distance + 0.1#0.4 + self.half_wire * 4
fake_center = vector(c.x + add_distance, ll.y - self.track_wire * 2 + offset)
is_too_close = any(abs(pin_added.center().x - fake_center.x) < (0.4 + self.half_wire * 4)for pin_added in self.io_pins_added_down)
if edge == "right":
fake_center = vector(ur.x + self.track_wire * 2 - offset, c.y)
is_too_close = any(abs(pin_added.center().y - fake_center.y) < (0.4 + self.half_wire * 4)for pin_added in self.io_pins_added_right)
while is_too_close:
debug.warning("overlap, changing position")
add_distance = add_distance + 0.1#0.4 + self.half_wire * 4
fake_center = vector(ur.x + self.track_wire * 2 - offset, c.y + add_distance)
# debug
for pin_added in self.io_pins_added_right:
dis = abs(pin_added.center().y - fake_center.y)
debug.warning("current position is {0}".format(fake_center))
debug.warning("distance from {0} is {1}".format(pin_added, dis))
debug.warning("must disrance is {0}".format(0.4 + self.half_wire * 4))
is_too_close = any(abs(pin_added.center().y - fake_center.y) < (0.4 + self.half_wire * 4)for pin_added in self.io_pins_added_right)
if edge == "top":
fake_center = vector(c.x, ur.y + self.track_wire * 2 - offset)
is_too_close = any(abs(pin_added.center().x - fake_center.x) < (0.4 + self.half_wire * 4)for pin_added in self.io_pins_added_up)
while is_too_close:
debug.warning("overlap, changing position")
add_distance = add_distance + 0.1#0.4 + self.half_wire * 4
fake_center = vector(c.x + add_distance, ur.y + self.track_wire * 2 - offset)
is_too_close = any(abs(pin_added.center().x - fake_center.x) < (0.4 + self.half_wire * 4)for pin_added in self.io_pins_added_up)
# Create the fake pin shape, here make sure the pin in the gds will be big enough
layer = self.get_layer(int(not vertical))
half_wire_vector = vector([self.half_wire] * 2)
nll = fake_center - half_wire_vector - half_wire_vector
nur = fake_center + half_wire_vector + half_wire_vector
rect = [nll, nur]
pin = graph_shape(name=pin.name + "_" + "fake",
rect=rect,
layer_name_pp=layer)
print("this create_fake_pin")
print(pin.name)
print(pin.center)
if edge == "left":
self.io_pins_added_left.append(pin)
elif edge == "bottom":
self.io_pins_added_down.append(pin)
elif edge == "right":
self.io_pins_added_right.append(pin)
elif edge == "top":
self.io_pins_added_up.append(pin)
debug.warning("pin added: {0}".format(pin))
return pin, vertical, add_distance
def add_io_pins(self, pin_names): def add_io_pins(self, pin_names):
""" Add IO pins on the edges WITHOUT routing them. """ """ Add IO pins on the edges WITHOUT routing them. """
debug.info(1, "Adding IO pins on the perimeter...") debug.info(1, "Adding IO pins on the perimeter...")
@ -543,4 +441,3 @@ class io_pin_placer(router):

View File

@ -20,7 +20,7 @@ class sram():
results. results.
We can later add visualizer and other high-level functions as needed. We can later add visualizer and other high-level functions as needed.
""" """
def __init__(self, sram_config=None, name=None): def __init__(self, sram_config=None, name=None, route_option="classic"):
# Create default configs if custom config isn't provided # Create default configs if custom config isn't provided
if sram_config is None: if sram_config is None:
@ -48,12 +48,16 @@ class sram():
start_time = datetime.datetime.now() start_time = datetime.datetime.now()
self.name = name self.name = name
self.route_option = route_option # "classic" or "fast"
from openram.modules.sram_1bank import sram_1bank as sram from openram.modules.sram_1bank import sram_1bank as sram
num_ports = OPTS.num_rw_ports + OPTS.num_r_ports + OPTS.num_w_ports num_ports = OPTS.num_rw_ports + OPTS.num_r_ports + OPTS.num_w_ports
self.s = sram(name, sram_config) self.s = sram(name, sram_config)
self.s.create_netlist()# not placed & routed jet self.s.create_netlist()# not placed & routed jet
# choose the routung method, maze router or constructive
if self.route_option == "classic":
cur_state = "IDLE" cur_state = "IDLE"
if not OPTS.netlist_only: if not OPTS.netlist_only:
i = 0 i = 0
@ -108,6 +112,9 @@ class sram():
else: else:
cur_state = "FINISH" cur_state = "FINISH"
break break
elif self.route_option == "fast":
if not OPTS.netlist_only:
self.s.create_layout(route_option=route_option)
if not OPTS.is_unit_test: if not OPTS.is_unit_test:
print_time("SRAM creation", datetime.datetime.now(), start_time) print_time("SRAM creation", datetime.datetime.now(), start_time)
@ -162,7 +169,7 @@ class sram():
spname = OPTS.output_path + self.s.name + ".sp" spname = OPTS.output_path + self.s.name + ".sp"
debug.print_raw("SP: Writing to {0}".format(spname)) debug.print_raw("SP: Writing to {0}".format(spname))
self.sp_write(spname) self.sp_write(spname)
''' #comment the following state when generating big sram, and then disable drc/lvs, because maigc_ext stuck #''' #comment the following state when generating big sram, and then disable drc/lvs, because maigc_ext stuck
# Save a functional simulation file with default period # Save a functional simulation file with default period
functional(self.s, functional(self.s,
spname, spname,
@ -184,7 +191,7 @@ class sram():
d.targ_write_ports = [self.s.write_ports[0]] d.targ_write_ports = [self.s.write_ports[0]]
d.write_delay_stimulus() d.write_delay_stimulus()
print_time("DELAY", datetime.datetime.now(), start_time) print_time("DELAY", datetime.datetime.now(), start_time)
''' #comment the above when generating big sram, and then disable drc/lvs, bevause magic_ext stuck #''' #comment the above when generating big sram, and then disable drc/lvs, bevause magic_ext stuck
# Save trimmed spice file # Save trimmed spice file
temp_trim_sp = "{0}trimmed.sp".format(OPTS.output_path) temp_trim_sp = "{0}trimmed.sp".format(OPTS.output_path)
self.sp_write(temp_trim_sp, lvs=False, trim=True) self.sp_write(temp_trim_sp, lvs=False, trim=True)

View File

@ -1,247 +0,0 @@
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2024 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 os
import shutil
import datetime
from openram import debug
from openram import sram_config as config
from openram import OPTS, print_time
class sram():
"""
This is not a design module, but contains an SRAM design instance.
It could later try options of number of banks and organization to compare
results.
We can later add visualizer and other high-level functions as needed.
"""
def __init__(self, sram_config=None, name=None):
# Create default configs if custom config isn't provided
if sram_config is None:
sram_config = config(word_size=OPTS.word_size,
num_words=OPTS.num_words,
write_size=OPTS.write_size,
num_banks=OPTS.num_banks,
words_per_row=OPTS.words_per_row,
num_spare_rows=OPTS.num_spare_rows,
num_spare_cols=OPTS.num_spare_cols)
if name is None:
name = OPTS.output_name
sram_config.set_local_config(self)
# reset the static duplicate name checker for unit tests
# in case we create more than one SRAM
from openram.base import design
design.name_map=[]
debug.info(2, "create sram of size {0} with {1} num of words {2} banks".format(self.word_size,
self.num_words,
self.num_banks))
start_time = datetime.datetime.now()
self.name = name
from openram.modules.sram_openroad import sram_1bank as sram
#from openram.modules.sram_new import sram_1bank as sram
self.s = sram(name, sram_config)
self.s.create_netlist()
if not OPTS.netlist_only:
self.s.create_layout_openroad()
if not OPTS.is_unit_test:
print_time("SRAM creation", datetime.datetime.now(), start_time)
def get_sp_name(self):
if OPTS.use_pex:
# Use the extracted spice file
return self.pex_name
else:
# Use generated spice file for characterization
return self.sp_name
def sp_write(self, name, lvs=False, trim=False):
self.s.sp_write(name, lvs, trim)
def lef_write(self, name):
self.s.lef_write(name)
def gds_write(self, name):
self.s.gds_write(name)
def verilog_write(self, name):
self.s.verilog_write(name)
if self.num_banks != 1:
from openram.modules.sram_multibank import sram_multibank
mb = sram_multibank(self.s)
mb.verilog_write(name[:-2] + '_top.v')
def extended_config_write(self, name):
"""Dump config file with all options.
Include defaults and anything changed by input config."""
f = open(name, "w")
var_dict = dict((name, getattr(OPTS, name)) for name in dir(OPTS) if not name.startswith('__') and not callable(getattr(OPTS, name)))
for var_name, var_value in var_dict.items():
if isinstance(var_value, str):
f.write(str(var_name) + " = " + "\"" + str(var_value) + "\"\n")
else:
f.write(str(var_name) + " = " + str(var_value)+ "\n")
f.close()
def save_only(self):
if not OPTS.netlist_only:
# Write the layout
start_time = datetime.datetime.now()
gdsname = OPTS.output_path + self.s.name + ".gds"
debug.print_raw("GDS: Writing to {0}".format(gdsname))
self.gds_write(gdsname)
if OPTS.check_lvsdrc:
verify.write_drc_script(cell_name=self.s.name,
gds_name=os.path.basename(gdsname),
extract=True,
final_verification=True,
output_path=OPTS.output_path)
print_time("GDS", datetime.datetime.now(), start_time)
# Create a LEF physical model
start_time = datetime.datetime.now()
lefname = OPTS.output_path + self.s.name + ".lef"
debug.print_raw("LEF: Writing to {0}".format(lefname))
self.lef_write(lefname)
print_time("LEF", datetime.datetime.now(), start_time)
def save(self):
""" Save all the output files while reporting time to do it as well. """
# Import this at the last minute so that the proper tech file
# is loaded and the right tools are selected
from openram import verify
from openram.characterizer import functional
from openram.characterizer import delay
# Save the spice file
start_time = datetime.datetime.now()
spname = OPTS.output_path + self.s.name + ".sp"
debug.print_raw("SP: Writing to {0}".format(spname))
self.sp_write(spname)
# Save a functional simulation file with default period
functional(self.s,
spname,
cycles=200,
output_path=OPTS.output_path)
print_time("Spice writing", datetime.datetime.now(), start_time)
# Save stimulus and measurement file
start_time = datetime.datetime.now()
debug.print_raw("DELAY: Writing stimulus...")
d = delay(self.s, spname, ("TT", 5, 25), output_path=OPTS.output_path)
if (self.s.num_spare_rows == 0):
probe_address = "1" * self.s.addr_size
else:
probe_address = "0" + "1" * (self.s.addr_size - 1)
probe_data = self.s.word_size - 1
d.analysis_init(probe_address, probe_data)
d.targ_read_ports.extend(self.s.read_ports)
d.targ_write_ports = [self.s.write_ports[0]]
d.write_delay_stimulus()
print_time("DELAY", datetime.datetime.now(), start_time)
# Save trimmed spice file
temp_trim_sp = "{0}trimmed.sp".format(OPTS.output_path)
self.sp_write(temp_trim_sp, lvs=False, trim=True)
if not OPTS.netlist_only:
# Write the layout
start_time = datetime.datetime.now()
gdsname = OPTS.output_path + self.s.name + ".gds"
debug.print_raw("GDS: Writing to {0}".format(gdsname))
self.gds_write(gdsname)
if OPTS.check_lvsdrc:
verify.write_drc_script(cell_name=self.s.name,
gds_name=os.path.basename(gdsname),
extract=True,
final_verification=True,
output_path=OPTS.output_path)
print_time("GDS", datetime.datetime.now(), start_time)
# Create a LEF physical model
start_time = datetime.datetime.now()
lefname = OPTS.output_path + self.s.name + ".lef"
debug.print_raw("LEF: Writing to {0}".format(lefname))
self.lef_write(lefname)
print_time("LEF", datetime.datetime.now(), start_time)
# Save the LVS file
start_time = datetime.datetime.now()
lvsname = OPTS.output_path + self.s.name + ".lvs.sp"
debug.print_raw("LVS: Writing to {0}".format(lvsname))
self.sp_write(lvsname, lvs=True)
if not OPTS.netlist_only and OPTS.check_lvsdrc:
verify.write_lvs_script(cell_name=self.s.name,
gds_name=os.path.basename(gdsname),
sp_name=os.path.basename(lvsname),
final_verification=True,
output_path=OPTS.output_path)
print_time("LVS writing", datetime.datetime.now(), start_time)
# Save the extracted spice file
if OPTS.use_pex:
start_time = datetime.datetime.now()
# Output the extracted design if requested
pexname = OPTS.output_path + self.s.name + ".pex.sp"
spname = OPTS.output_path + self.s.name + ".sp"
verify.run_pex(self.s.name, gdsname, spname, output=pexname)
sp_file = pexname
print_time("Extraction", datetime.datetime.now(), start_time)
else:
# Use generated spice file for characterization
sp_file = spname
# Characterize the design
start_time = datetime.datetime.now()
from openram.characterizer import lib
debug.print_raw("LIB: Characterizing... ")
lib(out_dir=OPTS.output_path, sram=self.s, sp_file=sp_file)
print_time("Characterization", datetime.datetime.now(), start_time)
# Write the config file
start_time = datetime.datetime.now()
try:
from shutil import copyfile
copyfile(OPTS.config_file, OPTS.output_path + OPTS.output_name + '.py')
except shutil.SameFileError:
pass
debug.print_raw("Config: Writing to {0}".format(OPTS.output_path + OPTS.output_name + '.py'))
print_time("Config", datetime.datetime.now(), start_time)
# Write the datasheet
start_time = datetime.datetime.now()
from openram.datasheet import datasheet_gen
dname = OPTS.output_path + self.s.name + ".html"
debug.print_raw("Datasheet: Writing to {0}".format(dname))
datasheet_gen.datasheet_write(dname)
print_time("Datasheet", datetime.datetime.now(), start_time)
# Write a verilog model
start_time = datetime.datetime.now()
vname = OPTS.output_path + self.s.name + '.v'
debug.print_raw("Verilog: Writing to {0}".format(vname))
self.verilog_write(vname)
print_time("Verilog", datetime.datetime.now(), start_time)
# Write out options if specified
if OPTS.output_extended_config:
start_time = datetime.datetime.now()
oname = OPTS.output_path + OPTS.output_name + "_extended.py"
debug.print_raw("Extended Config: Writing to {0}".format(oname))
self.extended_config_write(oname)
print_time("Extended Config", datetime.datetime.now(), start_time)

View File

@ -1,268 +0,0 @@
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2024 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.
#
# This file generate sram part, aiming at using openroad to do the P&R
import os
import shutil
import datetime
from openram import debug
from openram import sram_config as config
from openram import OPTS, print_time
class sram():
"""
This is not a design module, but contains an SRAM design instance.
It could later try options of number of banks and organization to compare
results.
We can later add visualizer and other high-level functions as needed.
"""
def __init__(self, sram_config=None, name=None, mod=0):
# Create default configs if custom config isn't provided
if sram_config is None:
sram_config = config(word_size=OPTS.word_size,
num_words=OPTS.num_words,
write_size=OPTS.write_size,
num_banks=OPTS.num_banks,
words_per_row=OPTS.words_per_row,
num_spare_rows=OPTS.num_spare_rows,
num_spare_cols=OPTS.num_spare_cols)
# maybe this part should be put after set_local_config, so we could calculate the number of port and define file name
if name is None:
#name = OPTS.output_name
if mod == 0:
name = OPTS.output_name + "_bank_" + "0"
elif mod == 1:# not consider multi-port yet!!!!!!
name = OPTS.output_name + "_control_" + "0"
elif mod == 2:
name = OPTS.output_name + "_row_addr_dff_" + "0"
elif mod == 3:
name = OPTS.output_name + "_col_addr_dff_" + "0"
elif mod == 4:
name = OPTS.output_name + "_data_dff_" + "0"
elif mod == 5:
name = OPTS.output_name + "_wmask_dff_" + "0"
elif mod == 6:
name = OPTS.output_name + "_spare_wen_dff_" + "0"
sram_config.set_local_config(self)
# reset the static duplicate name checker for unit tests
# in case we create more than one SRAM
from openram.base import design
design.name_map=[]
debug.info(2, "create sram of size {0} with {1} num of words {2} banks".format(self.word_size,
self.num_words,
self.num_banks))
start_time = datetime.datetime.now()
self.name = name
#from openram.modules.sram_1bank import sram_1bank as sram
from openram.modules.sram_for_road import sram_for_road as sram
self.s = sram(name, sram_config)
def get_sp_name(self):
if OPTS.use_pex:
# Use the extracted spice file
return self.pex_name
else:
# Use generated spice file for characterization
return self.sp_name
def sp_write(self, name, lvs=False, trim=False):
self.s.sp_write(name, lvs, trim)
def lef_write(self, name):
self.s.lef_write(name)
def gds_write(self, name):
self.s.gds_write(name)
def verilog_write(self, name):
self.s.verilog_write(name)
if self.num_banks != 1:
from openram.modules.sram_multibank import sram_multibank
mb = sram_multibank(self.s)
mb.verilog_write(name[:-2] + '_top.v')
def extended_config_write(self, name):
"""Dump config file with all options.
Include defaults and anything changed by input config."""
f = open(name, "w")
var_dict = dict((name, getattr(OPTS, name)) for name in dir(OPTS) if not name.startswith('__') and not callable(getattr(OPTS, name)))
for var_name, var_value in var_dict.items():
if isinstance(var_value, str):
f.write(str(var_name) + " = " + "\"" + str(var_value) + "\"\n")
else:
f.write(str(var_name) + " = " + str(var_value)+ "\n")
f.close()
def generate_files(self):
"""use to generate gds, lef files for one certain layout"""
# Import this at the last minute so that the proper tech file
# is loaded and the right tools are selected
from openram import verify
from openram.characterizer import functional
from openram.characterizer import delay
# Save the spice file
start_time = datetime.datetime.now()
spname = OPTS.output_path + self.s.name + ".sp"
debug.print_raw("SP: Writing to {0}".format(spname))
self.sp_write(spname)
print_time("Spice writing", datetime.datetime.now(), start_time)
# Save trimmed spice file
temp_trim_sp = "{0}trimmed.sp".format(OPTS.output_path)
self.sp_write(temp_trim_sp, lvs=False, trim=True)
if not OPTS.netlist_only:
# Write the layout
start_time = datetime.datetime.now()
gdsname = OPTS.output_path + self.s.name + ".gds"
debug.print_raw("GDS: Writing to {0}".format(gdsname))
self.gds_write(gdsname)
if OPTS.check_lvsdrc:
verify.write_drc_script(cell_name=self.s.name,
gds_name=os.path.basename(gdsname),
extract=True,
final_verification=True,
output_path=OPTS.output_path)
print_time("GDS", datetime.datetime.now(), start_time)
# Create a LEF physical model
start_time = datetime.datetime.now()
lefname = OPTS.output_path + self.s.name + ".lef"
debug.print_raw("LEF: Writing to {0}".format(lefname))
self.lef_write(lefname)
print_time("LEF", datetime.datetime.now(), start_time)
# Save the LVS file
start_time = datetime.datetime.now()
lvsname = OPTS.output_path + self.s.name + ".lvs.sp"
debug.print_raw("LVS: Writing to {0}".format(lvsname))
self.sp_write(lvsname, lvs=True)
if not OPTS.netlist_only and OPTS.check_lvsdrc:
verify.write_lvs_script(cell_name=self.s.name,
gds_name=os.path.basename(gdsname),
sp_name=os.path.basename(lvsname),
final_verification=True,
output_path=OPTS.output_path)
print_time("LVS writing", datetime.datetime.now(), start_time)
# Save the extracted spice file
if OPTS.use_pex:
start_time = datetime.datetime.now()
# Output the extracted design if requested
pexname = OPTS.output_path + self.s.name + ".pex.sp"
spname = OPTS.output_path + self.s.name + ".sp"
verify.run_pex(self.s.name, gdsname, spname, output=pexname)
sp_file = pexname
print_time("Extraction", datetime.datetime.now(), start_time)
else:
# Use generated spice file for characterization
sp_file = spname
# Write the config file
start_time = datetime.datetime.now()
try:
from shutil import copyfile
copyfile(OPTS.config_file, OPTS.output_path + OPTS.output_name + '.py')
except shutil.SameFileError:
pass
debug.print_raw("Config: Writing to {0}".format(OPTS.output_path + OPTS.output_name + '.py'))
print_time("Config", datetime.datetime.now(), start_time)
# Write a verilog model
start_time = datetime.datetime.now()
vname = OPTS.output_path + self.s.name + '.v'
debug.print_raw("Verilog: Writing to {0}".format(vname))
self.verilog_write(vname)
print_time("Verilog", datetime.datetime.now(), start_time)
# Write out options if specified
if OPTS.output_extended_config:
start_time = datetime.datetime.now()
oname = OPTS.output_path + OPTS.output_name + "_extended.py"
debug.print_raw("Extended Config: Writing to {0}".format(oname))
self.extended_config_write(oname)
print_time("Extended Config", datetime.datetime.now(), start_time)
def save(self, mod=0):
""" Save all the output files while reporting time to do it as well. """
if mod == 0:
self.s.create_netlist_bank()
if not OPTS.netlist_only:
self.s.create_layout_bank_only()
self.generate_files()
elif mod == 1:
self.s.create_netlist_control()
if not OPTS.netlist_only:
for port in self.s.all_ports:
self.s.create_layout_control_only(instance_index=port)
self.generate_files()
else:
for port in self.s.all_ports:
self.generate_files()
elif mod == 2:
self.s.create_netlist_row_addr_dff()
if not OPTS.netlist_only:
for port in self.s.all_ports:
self.s.create_layout_row_addr_dff_only(instance_index=port)
self.generate_files()
else:
for port in self.s.all_ports:
self.generate_files()
elif mod == 3:
if self.s.create_netlist_col_addr_dff() == False:
pass#continue # do not need col addr dff
elif not OPTS.netlist_only:
for port in self.s.all_ports:
self.create_layout_col_addr_dff_only(instance_index=port)
self.generate_files()
else:
self.generate_files()
elif mod == 4:
self.s.create_netlist_data_dff()
if not OPTS.netlist_only:
for port in self.s.all_ports:
self.s.create_layout_data_dff_only(instance_index=port)
self.generate_files()
else:
for port in self.s.all_ports:
self.generate_files()
elif mod == 5:
if self.s.create_netlist_wmask_dff() == False:
pass#continue # do not need wmask dff
elif not OPTS.netlist_only:
for port in self.s.all_ports:
self.s.create_layout_wmask_dff_only(instance_index=port)
self.generate_files()
else:
for port in self.s.all_ports:
self.generate_files()
elif mod == 6:
if self.s.create_netlist_spare_wen_dff() == False:
pass#continue # do not need spare wen dff
elif not OPTS.netlist_only:
for port in self.s.all_ports:
self.s.create_layout_spare_wen_dff_only(instance_index=port)
self.generate_files()
else:
for port in self.s.all_ports:
self.generate_files()

View File

@ -70,40 +70,10 @@ for path in output_files:
# Create an SRAM (we can also pass sram_config, see documentation/tutorials for details) # Create an SRAM (we can also pass sram_config, see documentation/tutorials for details)
from openram import sram from openram import sram
s = sram() s = sram(route_option="classic")# "classic" or "fast"
#from openram import sram_openroad_test
#s = sram_openroad_test.sram()
# Output the files for the resulting SRAM # Output the files for the resulting SRAM
s.save() s.save()
#s.save_only()
'''
from openram import sram_road
s = sram_road.sram(mod=0)
s.save(mod=0)
del s
s = sram_road.sram(mod=1)
s.save(mod=1)
del s
s = sram_road.sram(mod=2)
s.save(mod=2)
del s
s = sram_road.sram(mod=3)
s.save(mod=3)
del s
s = sram_road.sram(mod=4)
s.save(mod=4)
del s
s = sram_road.sram(mod=5)
s.save(mod=5)
del s
s = sram_road.sram(mod=6)
s.save(mod=6)
'''
# Delete temp files etc. # Delete temp files etc.
openram.end_openram() openram.end_openram()
openram.print_time("End", datetime.datetime.now(), start_time) openram.print_time("End", datetime.datetime.now(), start_time)