Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sram: fakeram vs. mock SRAM #151

Merged
merged 1 commit into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 68 additions & 5 deletions openroad.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -1215,6 +1215,8 @@ STAGE_IMPLS = [

ABSTRACT_IMPL = struct(stage = "generate_abstract", impl = orfs_abstract)

ALL_STAGES = ["synth", "floorplan", "place", "cts", "grt", "route", "final", "generate_abstract"]

# A stage argument is used in one or more stages. This is metainformation
# about the ORFS code that there is no known nice way for ORFS to
# provide.
Expand All @@ -1233,7 +1235,7 @@ STAGE_ARGS_USES = {
"TNS_END_PERCENT": ["cts", "floorplan", "grt"],
"SKIP_CTS_REPAIR_TIMING": ["cts"],
"CORE_MARGIN": ["floorplan"],
"SKIP_REPORT_METRICS": ["all"],
"SKIP_REPORT_METRICS": ["floorplan", "place", "cts", "grt", "route", "final"],
"SYNTH_HIERARCHICAL": ["synth"],
"RTLMP_FLOW": ["floorplan"],
"MACRO_PLACE_HALO": ["floorplan"],
Expand All @@ -1247,6 +1249,48 @@ STAGE_ARGS_USES = {
"ROUTING_LAYER_ADJUSTMENT": ["place", "grt", "route", "final"],
"FILL_CELLS": ["route"],
"TAPCELL_TCL": ["floorplan"],
"ADDITIONAL_LEFS": ALL_STAGES,
"ADDITIONAL_LIBS": ALL_STAGES,
}

def flatten(xs):
"""Flattens a nested list iteratively.

Args:
xs: A list that may contain other lists, maximum two levels
Returns:
A flattened list.
"""
result = []
for x in xs:
if type(x) == "list":
for y in x:
if type(y) == "list":
fail("Nested lists are not supported")
else:
result.append(y)
else:
result.append(x)
return result


def set(iterable):
"""Creates a set-like collection from an iterable.

Args:
iterable: An iterable containing elements.
Returns:
A list with unique elements.
"""
unique_dict = {}
for item in iterable:
unique_dict[item] = True
return list(unique_dict.keys())

STAGE_TO_VARIABLES = {
stage: [variable for variable, stages in STAGE_ARGS_USES.items()
if stage in stages]
for stage in ALL_STAGES
}

def get_stage_args(stage, stage_args, args):
Expand All @@ -1266,6 +1310,21 @@ def get_stage_args(stage, stage_args, args):
} |
stage_args.get(stage, {}))

def get_sources(stage, stage_sources, sources):
"""Returns the sources for a specific stage.

Args:
stage: The stage name.
stage_sources: the dictionary of stages with each stage having a list of sources
sources: a dictionary of variable names with a list of sources to a stage
Returns:
A list of sources for the stage.
"""
return set(stage_sources.get(stage, []) +
flatten([source_list for variable, source_list in sources.items()
if variable in STAGE_TO_VARIABLES[stage]]))


def _deep_dict_copy(d):
new_d = dict(d)
for k, v in new_d.items():
Expand All @@ -1278,6 +1337,7 @@ def _mock_area_targets(
steps,
verilog_files = [],
macros = [],
sources = {},
stage_sources = {},
stage_args = {},
args = {},
Expand Down Expand Up @@ -1307,7 +1367,7 @@ def _mock_area_targets(
synth_step.impl(
name = "{}_{}_mock_area".format(name_variant, synth_step.stage),
arguments = get_stage_args(synth_step.stage, stage_args, args),
data = stage_sources.get(synth_step.stage, []),
data = get_sources(synth_step.stage, stage_sources, sources),
deps = macros,
module_top = name,
variant = mock_variant,
Expand Down Expand Up @@ -1341,7 +1401,7 @@ def _mock_area_targets(
name = "{}_{}{}".format(name_variant, step.stage, suffix),
src = "{}_{}_mock_area".format(name_variant, prev.stage, suffix),
arguments = get_stage_args(step.stage, stage_args, args),
data = stage_sources.get(step.stage, []),
data = get_sources(step.stage, stage_sources, sources),
variant = mock_variant,
visibility = visibility,
**extra_args
Expand All @@ -1356,6 +1416,7 @@ def orfs_flow(
name,
verilog_files = [],
macros = [],
sources = {},
stage_sources = {},
stage_args = {},
args = {},
Expand All @@ -1370,6 +1431,7 @@ def orfs_flow(
name: name of the macro target
verilog_files: list of verilog sources of the design
macros: list of macros required to run physical design flow for this design
sources: dictionary keyed by ORFS variables with lists of sources
stage_sources: dictionary keyed by ORFS stages with lists of stage-specific sources
stage_args: dictionary keyed by ORFS stages with lists of stage-specific arguments
args: dictionary of additional arguments to the flow, automatically assigned to stages
Expand All @@ -1392,7 +1454,7 @@ def orfs_flow(
synth_step.impl(
name = "{}_{}".format(name_variant, synth_step.stage),
arguments = get_stage_args(synth_step.stage, stage_args, args),
data = stage_sources.get(synth_step.stage, []),
data = get_sources(synth_step.stage, stage_sources, sources),
deps = macros,
module_top = name,
variant = variant,
Expand All @@ -1409,7 +1471,7 @@ def orfs_flow(
name = "{}_{}".format(name_variant, step.stage),
src = "{}_{}".format(name_variant, prev.stage),
arguments = get_stage_args(step.stage, stage_args, args),
data = stage_sources.get(step.stage, []),
data = get_sources(step.stage, stage_sources, sources),
variant = variant,
visibility = visibility,
)
Expand All @@ -1427,6 +1489,7 @@ def orfs_flow(
steps,
verilog_files,
macros,
sources,
stage_sources,
stage_args,
args,
Expand Down
1 change: 1 addition & 0 deletions sram/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build/
105 changes: 105 additions & 0 deletions sram/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
load("//:openroad.bzl", "orfs_flow")

FAST_SETTINGS = {
"REMOVE_ABC_BUFFERS": "1",
"SKIP_REPORT_METRICS": "1",
"SKIP_CTS_REPAIR_TIMING": "1",
"SKIP_INCREMENTAL_REPAIR": "1",
}

orfs_flow(
name = "sdq_17x64",
abstract_stage = "grt",
mock_area = 0.95,
args = FAST_SETTINGS | {
"SDC_FILE": "$(location //sram:fakeram/constraints-sram.sdc)",
"CORE_UTILIZATION": "20",
"CORE_MARGIN": "2",
"MACRO_PLACE_HALO": "30 30",
"PLACE_DENSITY": "0.25",
},
stage_sources = {
"synth": ["//sram:fakeram/constraints-sram.sdc"],
},
verilog_files = ["//sram:fakeram/sdq_17x64.sv"],
)

orfs_flow(
name = "top",
abstract_stage = "grt",
macros = ["//sram:sdq_17x64_generate_abstract"],
args = FAST_SETTINGS | {
"SDC_FILE": "$(location //sram:fakeram/constraints-sram.sdc)",
"DIE_AREA": "0 0 100 100",
"CORE_AREA": "2 2 98 98",
"RTLMP_FLOW": "True",
"CORE_MARGIN": "2",
"MACRO_PLACE_HALO": "2 2",
},
stage_sources = {
"synth": ["//sram:fakeram/constraints-sram.sdc"],
},
verilog_files = ["//sram:fakeram/top.v"],
)

# buildifier: disable=duplicated-name
orfs_flow(
name = "top",
variant="fakeram",
abstract_stage = "grt",
args = FAST_SETTINGS | {
"SDC_FILE": "$(location //sram:fakeram/constraints-sram.sdc)",
"DIE_AREA": "0 0 30 30",
"CORE_AREA": "2 2 28 28",
"RTLMP_FLOW": "True",
"CORE_MARGIN": "2",
"MACRO_PLACE_HALO": "2 2",
"ADDITIONAL_LEFS": "$(location //sram:fakeram/sdq_17x64.lef)",
"ADDITIONAL_LIBS": "$(location //sram:fakeram/sdq_17x64.lib)",
},
sources = {
"ADDITIONAL_LEFS" : ["//sram:fakeram/sdq_17x64.lef"],
"ADDITIONAL_LIBS" : ["//sram:fakeram/sdq_17x64.lib"],
"SDC_FILE": ["//sram:fakeram/constraints-sram.sdc"],
},
verilog_files = ["//sram:fakeram/top.v"],
)

# buildifier: disable=duplicated-name
orfs_flow(
name = "sdq_17x64",
variant = "megaboom",
abstract_stage = "grt",
mock_area = 0.95,
args = FAST_SETTINGS | {
"SDC_FILE": "$(location //sram:megaboom/constraints-sram.sdc)",
"CORE_UTILIZATION": "20",
"CORE_MARGIN": "2",
"MACRO_PLACE_HALO": "30 30",
"PLACE_DENSITY": "0.25",
},
stage_sources = {
"synth": ["//sram:megaboom/constraints-sram.sdc"],
},
verilog_files = ["//sram:megaboom/sdq_17x64.sv"],
)

# buildifier: disable=duplicated-name
orfs_flow(
name = "top",
abstract_stage = "grt",
variant = "megaboom",
macros = ["//sram:sdq_17x64_megaboom_generate_abstract"],
args = FAST_SETTINGS | {
"SDC_FILE": "$(location //sram:megaboom/constraints-top.sdc)",
"DIE_AREA": "0 0 100 100",
"CORE_AREA": "2 2 98 98",
"RTLMP_FLOW": "True",
"CORE_MARGIN": "2",
"MACRO_PLACE_HALO": "2 2",
},
stage_sources = {
"synth": ["//sram:megaboom/constraints-top.sdc"],
},
verilog_files = ["//sram:megaboom/top.v"],
)
31 changes: 31 additions & 0 deletions sram/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
fakeram vs. mock SRAM
=====================

fakeram is a .lib, .lef and .v file generated by the fakeram tool.

mocked SRAM takes as input the design's behavioral model Verilog file and is used to generate a .lef and .lib file.

Mock SRAM based on fakeram's behavioral .v file
-----------------------------------------------

The .v file generated by fakeram does not build with yosys unmodified. The fakeram/sdq_17x64.sv has been manually pruned until it passed yosys.

bazel run //sram:top_grt `pwd`/build
build/make gui_grt

fakeram
-------

There is a problem with this setup: there is no clock visible in the OpenROAD GUI. A problem with the fakeram .lib file?

bazel run //sram:top_fakeram_grt `pwd`/build
build/make gui_grt


MegaBoom mock SRAM
------------------

A mock SRAM based on the MegaBoom behavioral Verilog.

bazel run //sram:top_megaboom_grt `pwd`/build
build/make gui_grt
9 changes: 9 additions & 0 deletions sram/fakeram/constraints-sram.sdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
set clk_name clk
set clk_port_name clk
set clk_period 400

if { [llength [all_registers]] > 0} {
source $env(PLATFORM_DIR)/constraints.sdc
} else {
puts "The design is gutted when mocking floorplan"
}
Loading