Adding version stuff.
diff --git a/scripts/python-skywater-pdk/skywater_pdk/base.py b/scripts/python-skywater-pdk/skywater_pdk/base.py
index c86cde2..65c51a7 100644
--- a/scripts/python-skywater-pdk/skywater_pdk/base.py
+++ b/scripts/python-skywater-pdk/skywater_pdk/base.py
@@ -21,15 +21,29 @@
 
     >>> t = list(parse_filename('sky130_fd_io-top_ground_padonlyv2-tt_1p80V_3p30V_3p30V_25C.wrap.lib'))
     >>> t.pop(0)
-    Cell(name='top_ground_padonlyv2', library=Library(node=LibraryNode.SKY130, source=LibrarySource('fd'), type=LibraryType.io, name=None))
+    Cell(name='top_ground_padonlyv2', library=Library(node=LibraryNode.SKY130, source=LibrarySource('fd'), type=LibraryType.io, name=None, version=None))
     >>> t.pop(0)
     'tt_1p80V_3p30V_3p30V_25C'
     >>> t.pop(0)
     'wrap.lib'
+    >>> t = list(parse_filename('v0.10.0/sky130_fd_sc_hdll-a211o-tt_1p80V_3p30V_3p30V_25C.wrap.json'))
+    >>> t.pop(0)
+    Cell(name='a211o', library=Library(node=LibraryNode.SKY130, source=LibrarySource('fd'), type=LibraryType.sc, name='hdll', version=LibraryVersion(milestone=0, major=10, minor=0, commits=0, hash='')))
+    >>> t.pop(0)
+    'tt_1p80V_3p30V_3p30V_25C'
+    >>> t.pop(0)
+    'wrap.json'
 
     """
     dirname, filename = os.path.split(pathname)
 
+
+    dirbase, dirversion = os.path.split(dirname)
+    try:
+        version = LibraryVersion.parse(dirversion)
+    except TypeError:
+        version = None
+
     if '.' in filename:
         basename, extension = filename.split('.', 1)
     else:
@@ -37,13 +51,98 @@
         extension = ''
     basename = basename.replace('-', SEPERATOR)
 
-    library, cell, extra = basename.split(SEPERATOR, 3)
-    return (Cell.parse(library+SEPERATOR+cell), extra, extension)
+    bits = basename.split(SEPERATOR, 3)
+    if len(bits) in (1, 2):
+        library = Library.parse(bits.pop(0))
+        extra = ""
+        if bits:
+            extra = bits.pop(0)
+        if version:
+            library.version = version
+    elif len(bits) == 3:
+        library = Cell.parse(bits[0]+SEPERATOR+bits[1])
+        if version:
+            library.library.version = version
+        extra = bits[2]
+    else:
+        raise NotImplementedError()
+
+    return (library, extra, extension)
 
 
 SEPERATOR = "__"
 
 
+@dataclass(order=True, frozen=True)
+class LibraryVersion:
+    """
+
+    >>> v0 = LibraryVersion.parse("v0.0.0")
+    >>> v0
+    LibraryVersion(milestone=0, major=0, minor=0, commits=0, hash='')
+    >>> v1a = LibraryVersion.parse("v0.0.0-10-g123abc")
+    >>> v1a
+    LibraryVersion(milestone=0, major=0, minor=0, commits=10, hash='123abc')
+    >>> v1b = LibraryVersion.parse("v0.0.0-4-g123abc")
+    >>> v1b
+    LibraryVersion(milestone=0, major=0, minor=0, commits=4, hash='123abc')
+    >>> v2 = LibraryVersion.parse("v0.0.2")
+    >>> v2
+    LibraryVersion(milestone=0, major=0, minor=2, commits=0, hash='')
+    >>> v3 = LibraryVersion.parse("v0.2.0")
+    >>> v3
+    LibraryVersion(milestone=0, major=2, minor=0, commits=0, hash='')
+    >>> v4 = LibraryVersion.parse("v0.0.10")
+    >>> v4
+    LibraryVersion(milestone=0, major=0, minor=10, commits=0, hash='')
+    >>> v0 < v1a
+    True
+    >>> v1a < v2
+    True
+    >>> v0 < v2
+    True
+    >>> l = [v1a, v2, v3, v1b, v0, v2]
+    >>> l.sort()
+    >>> [i.fullname for i in l]
+    ['0.0.0', '0.0.0-4-g123abc', '0.0.0-10-g123abc', '0.0.2', '0.0.2', '0.2.0']
+    """
+    milestone: int = 0
+    major: int = 0
+    minor: int = 0
+
+    commits: Optional[int] = 0
+    hash: Optional[str] = ''
+
+    @classmethod
+    def parse(cls, s):
+        if not s.startswith('v'):
+            raise TypeError("Unknown version: {}".format(s))
+        kw = {}
+        if '-' in s:
+            git_bits = s.split('-')
+            if len(git_bits) != 3:
+                raise TypeError("Unparsable git version: {}".format(s))
+            s = git_bits[0]
+            kw['commits'] = int(git_bits[1])
+            assert git_bits[2].startswith('g'), git_bits[2]
+            kw['hash'] = git_bits[2][1:]
+        kw['milestone'], kw['major'], kw['minor'] = (
+            int(i) for i in s[1:].split('.'))
+        return cls(**kw)
+
+    def as_tuple(self):
+        return (self.milestone, self.major, self.minor, self.commits, minor)
+
+    @property
+    def fullname(self):
+        o = []
+        s = "{}.{}.{}".format(
+            self.milestone, self.major, self.minor)
+        if self.commits:
+            s += "-{}-g{}".format(self.commits, self.hash)
+        return s
+
+
 class LibraryNode(Enum):
     SKY130 = "SkyWater 130nm"
 
@@ -119,7 +218,7 @@
 
     >>> l = Library.parse("sky130_fd_sc_hd")
     >>> l
-    Library(node=LibraryNode.SKY130, source=LibrarySource('fd'), type=LibraryType.sc, name='hd')
+    Library(node=LibraryNode.SKY130, source=LibrarySource('fd'), type=LibraryType.sc, name='hd', version=None)
     >>> l.fullname
     'sky130_fd_sc_hd'
     >>> l.source.fullname
@@ -129,7 +228,7 @@
 
     >>> l = Library.parse("sky130_rrr_sc_hd")
     >>> l
-    Library(node=LibraryNode.SKY130, source=LibrarySource('rrr'), type=LibraryType.sc, name='hd')
+    Library(node=LibraryNode.SKY130, source=LibrarySource('rrr'), type=LibraryType.sc, name='hd', version=None)
     >>> l.fullname
     'sky130_rrr_sc_hd'
     >>> l.source.fullname
@@ -142,6 +241,7 @@
     source: LibrarySource
     type: LibraryType
     name: Optional[str] = None
+    version: Optional[LibraryVersion] = None
 
     @property
     def fullname(self):
@@ -179,7 +279,7 @@
     """
     >>> c = Cell.parse("sky130_fd_sc_hd__abc")
     >>> c
-    Cell(name='abc', library=Library(node=LibraryNode.SKY130, source=LibrarySource('fd'), type=LibraryType.sc, name='hd'))
+    Cell(name='abc', library=Library(node=LibraryNode.SKY130, source=LibrarySource('fd'), type=LibraryType.sc, name='hd', version=None))
     >>> c.fullname
     'sky130_fd_sc_hd__abc'
 
diff --git a/scripts/python-skywater-pdk/skywater_pdk/corners.py b/scripts/python-skywater-pdk/skywater_pdk/corners.py
index 46c78de..d43c7d6 100644
--- a/scripts/python-skywater-pdk/skywater_pdk/corners.py
+++ b/scripts/python-skywater-pdk/skywater_pdk/corners.py
@@ -62,6 +62,17 @@
     nointpr = 'No internal power'
     lv = 'Low voltage'
     ccsnoise = 'Composite Current Source Noise'
+    ns5 = '5 nanoseconds'
+    pwr = 'Power'
+
+    @classmethod
+    def parse(cls, s):
+        if s == "5ns":
+            return cls.ns5
+        elif hasattr(cls, s):
+            return getattr(cls, s)
+        else:
+            raise TypeError("Unknown CornerFlags: {}".format(s))
 
     def __repr__(self):
         return 'CornerType.'+self.name
@@ -85,10 +96,34 @@
     >>> parse_filename('sky130_fd_io-top_ground_padonlyv2-tt_1p80V_3p30V_3p30V_25C.wrap.lib')
     Corner(volts=[1.8, 3.3, 3.3], temps=[25], flags=[], types=[CornerType.t, CornerType.t])
 
+    >>> parse_filename('sky130_fd_sc_ms-tt_1p80V_100C.wrap.json')
+    Corner(volts=[1.8], temps=[100], flags=[], types=[CornerType.t, CornerType.t])
+
+    >>> parse_filename('sky130_fd_sc_ms-tt_1p80V_100C.wrap.lib')
+    Corner(volts=[1.8], temps=[100], flags=[], types=[CornerType.t, CornerType.t])
+
+    >>> parse_filename('sky130_fd_sc_ms-tt_1p80V_25C_ccsnoise.wrap.json')
+    Corner(volts=[1.8], temps=[25], flags=[CornerType.ccsnoise], types=[CornerType.t, CornerType.t])
+
+    >>> parse_filename('sky130_fd_sc_ms-wp_1p56V_n40C_5ns.wrap.json')
+    Corner(volts=[1.56], temps=[-40], flags=[CornerType.ns5], types=[CornerType.f, CornerType.s])
+
+    >>> parse_filename('sky130_fd_sc_ms-wp_1p65V_n40C.wrap.json')
+    Corner(volts=[1.65], temps=[-40], flags=[], types=[CornerType.f, CornerType.s])
+
+    >>> parse_filename('sky130_fd_sc_ms-wp_1p95V_85C_pwr.wrap.lib')
+    Corner(volts=[1.95], temps=[85], flags=[CornerType.pwr], types=[CornerType.f, CornerType.s])
+
+    >>> parse_filename('sky130_fd_sc_ms-wp_1p95V_n40C_ccsnoise.wrap.json')
+    Corner(volts=[1.95], temps=[-40], flags=[CornerType.ccsnoise], types=[CornerType.f, CornerType.s])
+
+    >>> parse_filename('sky130_fd_sc_ms-wp_1p95V_n40C_pwr.wrap.lib')
+    Corner(volts=[1.95], temps=[-40], flags=[CornerType.pwr], types=[CornerType.f, CornerType.s])
+
     """
     cell, extra, extension = base_parse_filename(pathname)
 
-    if extension not in ('', 'lib', 'wrap.lib'):
+    if extension not in ('', 'lib', 'wrap.lib', 'wrap.json'):
         raise ValueError('Not possible to extract corners from: {!r}'.format(extension))
 
     if not extra:
@@ -109,11 +144,14 @@
         elif TEMP_REGEX.match(b):
             assert b.endswith('C'), b
             kw['temps'].append(int(b[:-1].replace('n', '-')))
-        elif hasattr(CornerFlag, b):
-            kw['flags'].append(getattr(CornerFlag, b))
         else:
-            assert 'types' not in kw, (kw, b)
-            kw['types'] = CornerType.parse(b)
+            try:
+                kw['flags'].append(CornerFlag.parse(b))
+            except TypeError as e:
+                if 'types' not in kw:
+                    kw['types'] = CornerType.parse(b)
+                else:
+                    raise
 
     return Corner(**kw)