Does anyone know a library (preferably python) to ...
# timing-closure
t
Does anyone know a library (preferably python) to create Liberty files ? I'm writing a ROM compiler and I need to write timings into a format that can be read by the flow when integrating the macro into the top level.
a
Hey Sylvain, let me know if you are still looking for a solution here. I wrote a simple Python script to create Liberty files as dictionaries and spit them out as valid, indented Liberty
I think the Google PDKs have similar functions, but mine is a lot simpler (~100 lines of code)
t
Yes, definitely still interested 😁
a
Copy code
def dict2liberty(liberty, current_group=None, indent=2, debug=False, dbg_logger=None):
  """Convert a dictionary to a Liberty library"""
  # If current_group is None, then this is the top-level group, take library
  if current_group is None:
    liberty, current_group = liberty["library"], "library"

  # Retrieve attributes and groups
  def isgroup(x):
    return isinstance(x, (dict, list))
  attributes = {k : v for k, v in liberty.items() if not isgroup(v) and k != "comment"}
  groupss = {k : v if isinstance(v, list) else [v] for k, v in liberty.items() if isgroup(v)}

  # Initialize liberty
  liberty = []

  # Attributes
  for k, v in attributes.items():
    if isinstance(v, tuple):
      text = f'{k} ('
      if isinstance(v[0], Iterable):
        text += " \\\n"
        text += ", \\\n".join([" "* indent + f'"{str(l)[1:-1].strip(",")}"' for l in v])
        text += " \\\n"
      elif isinstance(v[0], (int, float)):
        text += f'"{str(v)[1:-1].strip(",")}"'
      text += ");"
      liberty.append(text)
    elif k == "capacitive_load_unit":
      liberty.append(f"{k} ({v});")
    elif isinstance(v, str):
      liberty.append(f'{k} : "{v}";')
    else:
      liberty.append(f"{k} : {str(v).lower()};")

  # Groups (special groups have no name, e.g., "timing () {")
  special_groups = ["timing", "memory", "memory_read", "memory_write", "internal_power"]
  for group_name, groups in groupss.items():
    for group in groups:
      # Debug show cell
      if debug and current_group == "cell":
        <http://dbg_logger.info|dbg_logger.info>(f"DEBUG: Exporting cell {group_name}")

      # Group name header
      if not attributes:
        liberty.append(f"{current_group} ({group_name}) " + "{")
      elif group_name in special_groups:
        liberty.append(f"{group_name} () " + "{")

      # Add group name
      grouplib = dict2liberty(group, group_name, indent, debug, dbg_logger)

      # Indent
      if not attributes or group_name in special_groups:
        grouplib = [" "*indent + line for line in grouplib.split("\n")]
      else:
        grouplib = grouplib.split("\n")

      # Insert
      liberty.extend(grouplib)

      # Add closing brace
      if not attributes or group_name in special_groups:
        liberty.append("}")

  # Return final Liberty
  return "\n".join(liberty)
👌 1
t
Thanks.
Do you have an example usage by any chance ?
(example of output dict)
a
Yeah sorry. I can attach a few in a bit
(I assume you mean INPUT dict, as this is a dict2liberty function)
t
yes, input 😅
I think I started figuring it out, but an example to confirm would still be useful 🙂
a
Totally!
Ok here's an example with three cells: (1) synchronous DFF with enable, (2) AND gate, (3) memory. Example (3) is probably helpful for you
liberty.json
Let me know if you have any questions 🙂 I've been meaning to open-source my code for this but never gotten around to it. If you want to use it, it's under MIT license
1
t
Great, thanks !
a
Stopped being lazy and just made a repo for it haha
t
👌
😃 1
@Akash Levy Mmm, I your example file doesn't seem to work properly with the function.
I tried simply :
Copy code
import json

d = json.loads(open('example.json').read())
print(dict2liberty({'library':d}))
Ah, that's because
timing
must be a
tuple
and not a list and that's not representable in JSON ...
a
Yeah it’s not JSON it’s a python dictionary object with other Python primitives.
Could probably be modified to support JSON but doesn’t rn
Even though I called it a json file haha