Skip to content

Commit

Permalink
Add DRC using Magic (#76)
Browse files Browse the repository at this point in the history
* drc uses magic

* fix tap distance issue temp

* fix tap distance issue

* Fixed Tapping

+ Fills now add taps (doesn't appear to mess things up too much)
+ Added verible to env (just because)
+ Made DRC a separate option that acts on whatever the latest def is

Co-authored-by: Donn <[email protected]>
  • Loading branch information
ahmednofal and donn authored Jun 9, 2021
1 parent 618be36 commit c7206e5
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 14 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ tb_RAM*x*.v
build/
__pycache__
*.ext
support/
support/
/c2w
2 changes: 2 additions & 0 deletions dffram-env.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
FROM efabless/openlane:v0.15

RUN python3 -m pip install click pyyaml

RUN curl -L https://github.com/google/verible/releases/download/v0.0-1278-g660b3d5/verible-v0.0-1278-g660b3d5-CentOS-7.9.2009-Core-x86_64.tar.gz | tar --strip-components 1 -xzC /usr
64 changes: 57 additions & 7 deletions dffram.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,9 @@ def synthesis(build_folder, design, widths_supported, word_width_bytes, out_file

openlane("bash", "%s/synth.sh" % build_folder)

last_def = None
def floorplan(build_folder, design, wmargin_sites, hmargin_sites, width, height, in_file, out_file):
global last_def
SITE_WIDTH=0.46
SITE_HEIGHT=2.72
print("--- Floorplan ---")
Expand Down Expand Up @@ -249,9 +251,11 @@ def floorplan(build_folder, design, wmargin_sites, hmargin_sites, width, height,
))

openlane("openroad", "%s/fp_init.tcl" % build_folder)
last_def = out_file


def placeram(in_file, out_file, size, building_blocks, dimensions=os.devnull, represent=os.devnull):
global last_def
print("--- placeRAM Script ---")
unaltered = out_file + ".ref"

Expand All @@ -274,8 +278,11 @@ def placeram(in_file, out_file, size, building_blocks, dimensions=os.devnull, re
with open(out_file, 'w') as f:
f.write(altered_str)

last_def = out_file


def place_pins(build_folder, in_file, out_file, pin_order_file):
global last_def
print("--- Pin Placement ---")
openlane(
"python3",
Expand All @@ -293,6 +300,8 @@ def place_pins(build_folder, in_file, out_file, pin_order_file):
"-o", out_file
)

last_def = out_file

def verify_placement(build_folder, in_file):
print("--- Verify ---")
with open("%s/verify.tcl" % build_folder, 'w') as f:
Expand All @@ -308,9 +317,7 @@ def verify_placement(build_folder, in_file):
""".format(build_folder=build_folder,
pdk_liberty_dir=pdk_liberty_dir,
in_file=in_file)


)
)

openlane("openroad", "%s/verify.tcl" % build_folder)

Expand All @@ -332,6 +339,7 @@ def create_image(build_folder, in_file, width=256,height=256):
last_image = in_file + ".png"

def pdngen(build_folder, width, height, in_file, out_file):
global last_def
print("--- Power Distribution Network Construction ---")
pitch = 50 # temp: till we arrive at a function that takes in width
offset = 25 # temp: till we arrive at a function that takes in width
Expand Down Expand Up @@ -395,6 +403,7 @@ def pdngen(build_folder, width, height, in_file, out_file):
openlane("openroad", "%s/pdn.tcl" % build_folder)

def obs_route(build_folder, metal_layer, width, height, in_file, out_file):
global last_def
print("--- Routing Obstruction Creation---")
openlane(
"python3",
Expand All @@ -406,8 +415,10 @@ def obs_route(build_folder, metal_layer, width, height, in_file, out_file):
width=width,
height=height),
"--output", out_file)
last_def = out_file

def route(build_folder, in_file, out_file):
global last_def
print("--- Route ---")
global_route_guide = "%s/gr.guide" % build_folder
with open("%s/tr.param" % build_folder, 'w') as f:
Expand Down Expand Up @@ -443,6 +454,7 @@ def route(build_folder, in_file, out_file):
build_folder=build_folder))

openlane("openroad", "%s/route.tcl" % build_folder)
last_def = out_file

def spef_extract(build_folder, def_file, spef_file=None):
print("--- Extract SPEF ---")
Expand All @@ -455,6 +467,7 @@ def spef_extract(build_folder, def_file, spef_file=None):
def add_pwr_gnd_pins(build_folder, original_netlist,
def_file, intermediate_file, out_file1,
out_file2):
global last_def
print("--- Adding power and ground pins to netlist ---")

openlane("python3", "/openLANE_flow/scripts/write_powered_def.py",
Expand Down Expand Up @@ -487,6 +500,7 @@ def add_pwr_gnd_pins(build_folder, original_netlist,
""".format(verilog_file=out_file1, out_file=out_file2))

openlane("yosys", "-c", "%s/rewrite_netlist.tcl" % build_folder)
last_def = out_file2


def write_ram_lef(build_folder, design, in_file, out_file):
Expand Down Expand Up @@ -519,6 +533,34 @@ def write_ram_lib(build_folder, design, netlist, libfile):
netlist,
libfile)

def magic_drc(build_folder, design, def_file):
print("--- Magic DRC ---")
with open("%s/drc.tcl" % build_folder, "w") as f:
f.write("""
set ::env(MAGIC_DRC_USE_GDS) 0
set ::env(TECH_LEF) {pdk_tlef_dir}/sky130_fd_sc_hd.tlef
set ::env(magic_report_file_tag) {def_file}
set ::env(magic_result_file_tag) {def_file}
set ::env(CURRENT_DEF) {def_file}
set ::env(DESIGN_NAME) {design}
source /openLANE_flow/scripts/magic/drc.tcl
""".format(pdk_tlef_dir=pdk_tlef_dir, design=design, def_file=def_file))
openlane("magic",
"-dnull",
"-noconsole",
"-rcfile",
"%s/sky130A.magicrc" % pdk_magic_dir,
"%s/drc.tcl" % build_folder)
drc_report = "%s.drc" % def_file
drc_report_str = open(drc_report).read()
count = r"COUNT:\s*(\d+)"
errors = 0
count_match = re.search(count, drc_report_str)
if count_match is not None:
errors = int(count_match[1])
if errors != 0:
print("Error: There are %i DRC errors. Check %s." % (errors, drc_report))
exit(65)

def lvs(build_folder, design, in_1, in_2, report):
print("--- LVS ---")
Expand Down Expand Up @@ -575,19 +617,20 @@ def antenna_check(build_folder, def_file, out_file):


@click.command()
@click.option("-f", "--frm", default="synthesis", help="Start from this step")
@click.option("-f", "--from", "frm", default="synthesis", help="Start from this step")
@click.option("-t", "--to", default="lvs", help="End after this step")
@click.option("--only", default=None, help="Only execute these comma;delimited;steps")
@click.option("--skip", default=None, help="Skip these comma;delimited;steps")
@click.option("-p", "--pdk_root", required=os.getenv("PDK_ROOT") is not None, default=os.getenv("PDK_ROOT"), help="path to sky130A pdk")
@click.option("-s", "--size", required=True, help="Size")
@click.option("-b", "--building-blocks", default="sky130A:ram/legacy", help="Format <pdk>:<name>: Name of the building blocks to use.")
@click.option("-v", "--variant", default=None, help="Use design variants (such as 1RW1R)")
def flow(frm, to, only, pdk_root, skip, size, building_blocks, variant):
global bb_used
@click.option("--drc/--no-drc", default=True, help="Perform DRC on latest generated def file. (Default: True)")
def flow(frm, to, only, pdk_root, skip, size, building_blocks, variant, drc):
global bb_used, last_def, last_image

subprocess.run([
"docker", "build", "-t", "dffram-env", "-f", "dffram-env.Dockerfile", "."
"docker", "build", "-t", "dffram-env", "-f", "dffram-env.Dockerfile", "."
], check=True)

if variant == "DEFAULT":
Expand Down Expand Up @@ -663,6 +706,7 @@ def i(ext=""):
powered_netlist = i(".powered.nl.v")
antenna_report = i(".antenna.rpt")
report = i(".rpt")
drc_report = i(".drc.rpt")

try:
width, height = map(lambda x: float(x), open(dimensions_file).read().split("x"))
Expand Down Expand Up @@ -782,6 +826,9 @@ def placement(in_width, in_height):
if to == name:
execute_steps = False

if drc:
magic_drc(build_folder, design, last_def)

elapsed = time.time() - start

if last_image is not None:
Expand Down Expand Up @@ -809,6 +856,9 @@ def placement(in_width, in_height):
def main():
try:
flow()
except subprocess.CalledProcessError as e:
print("A step has failed:", e)
exit(69)
except Exception:
print("An unhandled exception has occurred.", traceback.format_exc())
exit(69)
Expand Down
5 changes: 4 additions & 1 deletion placeram/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
except:
print("""
placeram needs to be inside OpenROAD:
openroad -python -m placeram [args]
""")
exit(78)
Expand Down Expand Up @@ -125,6 +125,9 @@ def create_fill(name, sites=1):
elif word_count == 512:
self.hierarchy = \
HigherLevelPlaceable(includes[128], self.instances)
elif word_count == 1024:
self.hierarchy = \
HigherLevelPlaceable(includes[512], self.instances)
elif word_count == 2048:
self.hierarchy = \
HigherLevelPlaceable(includes[512], self.instances)
Expand Down
7 changes: 3 additions & 4 deletions placeram/row.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from opendbpy import dbRow, dbInst, dbSite
from typing import List, Callable

Expand Down Expand Up @@ -62,8 +62,6 @@ def tap(self, width: float=0):
self.place(Row.create_tap("tap_%i_%i" % (self.ordinal, self.tap_counter)), ignore_tap=True)
self.tap_counter += 1
self.since_last_tap = 0
else:
self.since_last_tap += width

def place(self, instance: dbInst, ignore_tap: bool =False):
width = instance.getMaster().getWidth()
Expand All @@ -74,6 +72,7 @@ def place(self, instance: dbInst, ignore_tap: bool =False):
instance.setLocation(self.x, self.y)
instance.setPlacementStatus("PLACED")

self.since_last_tap += width
self.x += width
self.cell_counter += 1

Expand Down Expand Up @@ -165,5 +164,5 @@ def pack(size, fill_sizes):

for fill in fills:
fill_cell = Row.create_fill("fill_%i_%i" % (row_idx, r.fill_counter), fill)
r.place(fill_cell, ignore_tap=True)
r.place(fill_cell)
r.fill_counter += 1
2 changes: 1 addition & 1 deletion platforms/sky130A/BB/ram/config.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
lib: sky130_fd_sc_hd
widths: [8, 16, 24, 32, 40, 48, 56, 64]
counts: [8, 32, 128]
counts: [8, 32, 128, 256, 512, 1024, 2048]
design_name_template: "RAM{count}{variant}"
variants:
- null
Expand Down

0 comments on commit c7206e5

Please sign in to comment.