diff --git a/.github/workflows/asic.yaml b/.github/workflows/asic.yaml new file mode 100644 index 000000000..0206800d4 --- /dev/null +++ b/.github/workflows/asic.yaml @@ -0,0 +1,79 @@ +name: "Torii-HDL Tests - ASIC" +on: + push: + branches: + - '**/**asic**' + +jobs: + test-torii-asic-openlane: + name: Torii OpenLANE Test + runs-on: ubuntu-latest + env: + OPENLANE_IMAGE_NAME: efabless/openlane:latest + OPENLANE_ROOT: /home/runner/work/torii-hdl/torii-hdl/openlane + PDK_ROOT: /home/runner/work/torii-hdl/torii-hdl/pdk + PDK_TAG: 3df14f84ab167baf757134739bb1d2c5c044849c + TORII_OPENLANE_ROOT: ${OPENLANE_ROOT} + TORII_PDK_ROOT: ${PDK_ROOT} + + steps: + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: 3.11 + + - name: Initialize Env + shell: bash + env: + WORKSPACE: ${{ github.workspace }} + run: | + echo "$HOME/.local/bin:$PATH" >> $GITHUB_PATH + echo "GITHUB_WORKSPACE=\"`pwd`\"" >> $GITHUB_ENV + + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup OSS CAD Suite + uses: YosysHQ/setup-oss-cad-suite@v3 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Install magic + klayout + run: | + sudo apt-get update + sudo apt-get install klayout magic + + - name: Setup + shell: bash + run: | + python -m pip install --user --upgrade pip setuptools wheel setuptools_scm nox volare + + - name: Checkout OpenLANE + uses: actions/checkout@v3 + with: + repository: 'The-OpenROAD-Project/OpenLane' + ref: '2023.06.22' + path: 'openlane' + fetch-depth: 1 + + - name: Setup PDK / OpenLane + shell: bash + run: | + volare enable --pdk sky130 ${PDK_TAG} + pushd ${OPENLANE_ROOT} + make + make test + popd + + + - name: Run ASIC Tests + shell: bash + run: | + nox -s test -- --asic --coverage + + - name: Codecov Upload + uses: codecov/codecov-action@v4 + with: + verbose: true + files: ./build/tests/coverage.xml + token: ${{ secrets.CODECOV_TOKEN }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 560ca7f8c..df07f7554 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ Unreleased template stuff ### Added - Added new `torii.platform.formal.FormalPlatform` for formal verification of Torii designs. + - Added `torii.vendor.asic` OpenLANE ASIC flow support ### Changed @@ -92,20 +93,6 @@ Unreleased template stuff ### Fixed - - Fixed `ToriiTestCase.settle` to handle "0" count settles. - - Fixed `torii.hdl.dsl.Module`'s constructor to properly use `super()` rather than a parent class name call. - - Load of typing annotation fixes. - - Cleaned up a load of blank `asserts`, they should now have more clear error diagnostics. - - Fixed a handful of typos throughout the library and documentation. - - Fixed tracer calls for Python 3.13 - - Fixed `Array` not being indexable by a `ValueCastable`. - - Fixed `ValueCastable` not being accepted as a simulation coroutine command. - - Fixed handling of redundant `Case` branches. - - Fixed `Value.shift_right` and `Value.as_signed` edge cases. - - Fixed using 0-width `Switch`'s with integer keys. - - Trying to use the Python `in` operator on a `Value` now raises a sensible error. - - When indexing or slicing a Value with another Value, it now raises an error and suggests to use `Value.bit_select` or `Value.word_select` instead. - - Fixed simulation look when process catches an injected exception. ## [0.5.0] diff --git a/README.md b/README.md index f06b19b60..d54ec507c 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,40 @@ Torii can be used to target any FPGA or ASIC process that accepts behavioral Ver +> **Warning** ASIC Flow targets are super experimental +> and unstable at the moment. +> Please don't use these for production in any capacity. + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ASICToolchain
FOSSProprietary
sky130OpenLANE
sky90
gf180mcu
+ + ## License Torii is released under the [BSD-2-Clause](https://spdx.org/licenses/BSD-2-Clause.html), the full text of which can be found in the [LICENSE](LICENSE) file. diff --git a/docs/platforms/asic/index.md b/docs/platforms/asic/index.md new file mode 100644 index 000000000..962fcae62 --- /dev/null +++ b/docs/platforms/asic/index.md @@ -0,0 +1,5 @@ +# Torii ASIC Platforms + +```{warning} +ASIC Support in Torii is not stable, use at your own risk +``` diff --git a/examples/asic/alu.py b/examples/asic/alu.py new file mode 100644 index 000000000..a03809067 --- /dev/null +++ b/examples/asic/alu.py @@ -0,0 +1,37 @@ +# SPDX-License-Identifier: BSD-2-Clause + +from torii import Elaboratable, Module, Signal, Cat +from torii.platform.asic.sky130 import Sky130BHighDensityPlatform + +class ALU(Elaboratable): + def __init__(self, width: int): + self.sel = Signal(2) + self.a = Signal(width) + self.b = Signal(width) + self.o = Signal(width) + self.co = Signal() + + def elaborate(self, platform) -> Module: + m = Module() + with m.If(self.sel == 0b00): + m.d.comb += self.o.eq(self.a | self.b) + with m.Elif(self.sel == 0b01): + m.d.comb += self.o.eq(self.a & self.b) + with m.Elif(self.sel == 0b10): + m.d.comb += self.o.eq(self.a ^ self.b) + with m.Else(): + m.d.comb += Cat(self.o, self.co).eq(self.a - self.b) + return m + +class ExampleFlow(Sky130BHighDensityPlatform): + flow_settings = { + 'DESIGN_IS_CORE': 0, + } + connectors = () + resources = () + +if __name__ == '__main__': + alu = ALU(width = 16) + flow = ExampleFlow() + + flow.build(alu, name = 'alu', ports = [alu.sel, alu.a, alu.b, alu.o, alu.co]) diff --git a/examples/asic/counter.py b/examples/asic/counter.py new file mode 100644 index 000000000..e1cd98bbd --- /dev/null +++ b/examples/asic/counter.py @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: BSD-2-Clause + +from torii import Elaboratable, Signal, Module +from torii.build import Resource, Clock, Pins +from torii.platform.asic.sky130 import Sky130BHighDensityPlatform + +class Counter(Elaboratable): + def __init__(self, width: int): + self.v = Signal(width, reset = 2**width-1) + self.o = Signal() + + def elaborate(self, platform) -> Module: + m = Module() + m.d.sync += self.v.eq(self.v + 1) + m.d.comb += self.o.eq(self.v[-1]) + return m + +class ExampleFlow(Sky130BHighDensityPlatform): + default_clk = 'clk' + + flow_settings = { + 'FP_CORE_UTIL': 1, + 'DESIGN_IS_CORE': 0, + } + + connectors = () + resources = ( + Resource('clk', 0, + Pins('C', dir = 'i'), + Clock(1e6) + ), + ) + +if __name__ == '__main__': + ctr = Counter(width = 16) + flow = ExampleFlow() + + flow.build(ctr, name = 'ctr', ports = [ctr.o]) diff --git a/examples/asic/fsm.py b/examples/asic/fsm.py new file mode 100644 index 000000000..3926cac24 --- /dev/null +++ b/examples/asic/fsm.py @@ -0,0 +1,85 @@ +# SPDX-License-Identifier: BSD-2-Clause + +from torii import Elaboratable, Module, Signal, Cat +from torii.build import Resource, Clock, Pins +from torii.platform.asic.sky130 import Sky130BHighDensityPlatform + + +class UARTReceiver(Elaboratable): + def __init__(self, divisor: int): + self.divisor = divisor + + self.i = Signal() + self.data = Signal(8) + self.rdy = Signal() + self.ack = Signal() + self.err = Signal() + + def elaborate(self, platform) -> Module: + m = Module() + + ctr = Signal(range(self.divisor)) + stb = Signal() + with m.If(ctr == 0): + m.d.sync += ctr.eq(self.divisor - 1) + m.d.comb += stb.eq(1) + with m.Else(): + m.d.sync += ctr.eq(ctr - 1) + + bit = Signal(3) + with m.FSM() as fsm: + with m.State('START'): + with m.If(~self.i): + m.next = 'DATA' + m.d.sync += [ + ctr.eq(self.divisor // 2), + bit.eq(7), + ] + with m.State('DATA'): + with m.If(stb): + m.d.sync += [ + bit.eq(bit - 1), + self.data.eq(Cat(self.i, self.data)) + ] + with m.If(bit == 0): + m.next = 'STOP' + with m.State('STOP'): + with m.If(stb): + with m.If(self.i): + m.next = 'DONE' + with m.Else(): + m.next = 'ERROR' + + with m.State('DONE'): + m.d.comb += self.rdy.eq(1) + with m.If(self.ack): + m.next = 'START' + + m.d.comb += self.err.eq(fsm.ongoing('ERROR')) + with m.State('ERROR'): + pass + + return m + + +class ExampleFlow(Sky130BHighDensityPlatform): + default_clk = 'clk' + + flow_settings = { + 'FP_CORE_UTIL': 50, + 'DESIGN_IS_CORE': 0, + } + + connectors = () + resources = ( + Resource('clk', 0, + Pins('C', dir = 'i'), + Clock(1e6) + ), + ) + +if __name__ == '__main__': + rx = UARTReceiver(10) + flow = ExampleFlow() + + flow.build(rx, name = 'fsm', ports = [rx.i, rx.data, rx.rdy, rx.ack, rx.err]) diff --git a/noxfile.py b/noxfile.py index 01ba4f19a..2652d9027 100644 --- a/noxfile.py +++ b/noxfile.py @@ -44,6 +44,7 @@ def test(session: Session) -> None: out_dir.mkdir(parents = True, exist_ok = True) coverage = '--coverage' in session.posargs formal = '--formal' in session.posargs + asic = '--asic' in session.posargs unitest_args = ('-m', 'unittest', 'discover', '-s', str(ROOT_DIR)) @@ -70,11 +71,18 @@ def test(session: Session) -> None: session.run( 'python', *coverage_args, example ) - else: - session.log('Running standard test suite') + elif asic: + ASIC_EXAMPLES = ROOT_DIR / 'examples' / 'asic' + + session.log('Running ASIC tests') session.run( - 'python', *coverage_args, *unitest_args + 'python', *coverage_args, f'{ASIC_EXAMPLES / "alu.py"}' ) + else: + session.log('Running standard tests') + session.run( + 'python', *coverage_args, *unitest_args + ) if coverage: session.run( 'python', '-m', 'coverage', 'xml', diff --git a/torii/platform/asic/__init__.py b/torii/platform/asic/__init__.py new file mode 100644 index 000000000..3ff4dc2a3 --- /dev/null +++ b/torii/platform/asic/__init__.py @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: BSD-3-Clause + +from .sky130 import ( + Sky130BHighDensityPlatform, + Sky130BHighSpeedPlatform, + Sky130BMediumSpeedPlatform, + Sky130BLowSpeedPlatform, + Sky130BHighDensityLowLeakagePlatform, +) + + +__all__ = ( + 'Sky130BHighDensityPlatform', + 'Sky130BHighSpeedPlatform', + 'Sky130BMediumSpeedPlatform', + 'Sky130BLowSpeedPlatform', + 'Sky130BHighDensityLowLeakagePlatform', +) diff --git a/torii/platform/asic/efabless_caravel.py b/torii/platform/asic/efabless_caravel.py new file mode 100644 index 000000000..5d9b11d03 --- /dev/null +++ b/torii/platform/asic/efabless_caravel.py @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: BSD-2-Clause + +from .openlane import OpenLANEPlatform + + +__all__ = ( + 'OpenLANEPlatform', +) + +class EfablessCaravel(OpenLANEPlatform): + + def __init__(self) -> None: + super().__init__() diff --git a/torii/platform/asic/gf180mcu.py b/torii/platform/asic/gf180mcu.py new file mode 100644 index 000000000..73959e760 --- /dev/null +++ b/torii/platform/asic/gf180mcu.py @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: BSD-3-Clause + +from .openlane import OpenLANEPlatform # noqa: F401 diff --git a/torii/platform/asic/openlane.py b/torii/platform/asic/openlane.py new file mode 100644 index 000000000..209c0f849 --- /dev/null +++ b/torii/platform/asic/openlane.py @@ -0,0 +1,223 @@ +# SPDX-License-Identifier: BSD-2-Clause + +from abc import abstractmethod +from typing import Union, Optional +from pathlib import Path + +from ...build.plat import TemplatedPlatform +from ...build.run import BuildPlan +from ...hdl.ir import Fragment + +__all__ = ( + 'OpenLANEPlatform', +) + +class OpenLANEPlatform(TemplatedPlatform): + ''' + .. note:: + + See https://github.com/The-OpenROAD-Project/OpenLane#setting-up-openlane for instructions on + setting up OpenLANE and the various PDKs. + + .. note:: + + See https://openlane.readthedocs.io/en/latest/configuration/README.html#variables-information for + more detailed information on the various ``flow_settings`` available. + + Required tools: + * ``OpenLANE`` + * ``docker`` + + Build products: + * ``config.tcl``: OpenLANE Flow configuration + * ``{{name}}.sdc``: Timing and clock constraints + * ``{{name}}.v``: Design Verilog + * ``{{name}}.debug.v``: Design debug verilog + * ``runs/*``: OpenLANE flow output + + ''' + + openlane_root : Optional[Path] = None + pdk_root : Optional[Path] = None + toolchain = 'openlane' + + @property + @abstractmethod + def pdk(self) -> str: + raise NotImplementedError('Platform must implement this property') + + @property + @abstractmethod + def cell_library(self) -> str: + raise NotImplementedError('Platform must implement this property') + + @property + @abstractmethod + def flow_settings(self) -> dict[str, Union[str, int, float]]: + raise NotImplementedError('Platform must implement this property') + + _openlane_required_tools = ( + 'docker', + ) + + _openlane_file_templates = { + 'build_{{name}}.sh': ''' + # {{autogenerated}} + set -e{{verbose("x")}} + [ -n "${{platform._toolchain_env_var}}" ] && . "${{platform._toolchain_env_var}}" + {{emit_commands("sh")}} + ''', + '{{name}}.v': r''' + /* {{autogenerated}} */ + {{emit_verilog()}} + ''', + '{{name}}.debug.v': r''' + /* {{autogenerated}} */ + {{emit_debug_verilog()}} + ''', + 'config.tcl': r''' + # {{autogenerated}} + # Design Information + set ::env(DESIGN_NAME) "{{name}}" + set ::env(VERILOG_FILES) "/design_{{name}}/{{name}}.v" + set ::env(SDC_FILE) "/design_{{name}}/{{name}}.sdc" + {% if platform.default_clk %} + # Clocking Settings + # TODO: We assume the clock is in MHz here, + set ::env(CLOCK_PERIOD) {{(platform.default_clk_constraint.period / 1e-9)|round}} + set ::env(CLOCK_PORT) "{{platform._default_clk_name}}" + set ::env(CLOCK_NET) $::env(CLOCK_PORT) + {% else %} + # No Clock + set ::env(RUN_CTS) 0 + set ::env(CLOCK_PORT) "" + {% endif %} + # PDK Settings + set ::env(PDK) "{{platform.pdk}}" + set ::env(STD_CELL_LIBRARY) "{{platform.cell_library}}" + # Design "{{name}}" Specific flow settings + {% for e, v in platform.flow_settings.items() %} + set ::env({{e}}) {{v}} + {% endfor %} + # Pull in {{platform.pdk}} settings + set pdk_config $::env(DESIGN_DIR)/$::env(PDK)_$::env(STD_CELL_LIBRARY)_config.tcl + if { [file exists $pdk_config] == 1 } { + source $pdk_config + } + ''', + '{{name}}.sdc': r''' + # {{autogenerated}} + set_units -time ns + {% for net_sig, port_sig, frq in platform.iter_clock_constraints() -%} + {% if port_sig is not none -%} + create_clock -name {{port_sig.name|tcl_escape}} -period {{frq}} [get_ports {{port_sig.name|tcl_escape}}] + {% else -%} + create_clock -name {{net_sig.name|tcl_escape}} -period {{frq}} [get_nets {{net_sig.name|hierarchy("/")|tcl_escape}}] + {% endif -%} + {% endfor %} + {{get_override("add_constraints")|default("# (add_constraints placeholder)")}} + ''', # noqa: E501 + 'run_flow_{{name}}.sh': r''' + ./flow.tcl {{verbose("-verbose 2")}} \ + -design /design_{{name}} \ + -config_file /design_{{name}}/config.tcl {{get_override("flow_opts")|options}} + ''' + } + + _openlane_command_templates = ( + r''' + {{invoke_tool("docker")}} + rm "torii-openlane-{{name}}" &> /dev/null || true + ''', + r''' + {{invoke_tool("docker")}} + run + {% if get_override_flag("openlane_interactive") %} + -it + {% endif %} + {% if not get_override_flag("docker_networked") %} + --network none + {% endif %} + --rm + --name "torii-openlane-{{name}}" + -v {{get_override("OPENLANE_ROOT")|default(platform.openlane_root)}}:/openLANE_flow + -v {{get_override("PDK_ROOT")|default(platform.pdk_root)}}:/PDK + -v {{platform._build_dir}}:/design_{{name}} + -e PDK_ROOT=/PDK + -u $(id -u):$(id -g) + efabless/openlane:{{get_override("OPENLANE_TAG")|default("latest")}} + sh /design_{{name}}/run_flow_{{name}}.sh + ''', + ) + + _build_dir : Optional[Path] = None + + def __init__( + self, *, + PDK_root: Optional[Union[str, Path]] = None, OpenLANE_root: Optional[Union[str, Path]] = None + ) -> None: + ''' + + Parameters + ---------- + PDK_root: Optional[Union[str, Path]] + The path to the root where the PDK is located + ( default: /opt/PDK ) + + OpenLANE_root: Optional[Union[str, Path]] + The path to the local install of OpenLANE + ( default: /opt/OpenLANE ) + + ''' + + super().__init__() + + if PDK_root is not None: + self.pdk_root = PDK_root + else: + self.pdk_root = '/opt/PDK' + + if OpenLANE_root is not None: + self.openlane_root = OpenLANE_root + else: + self.openlane_root = '/opt/OpenLANE' + + + @property + def required_tools(self) -> tuple[str]: + return self._openlane_required_tools + + @property + def file_templates(self) -> dict[str, str]: + return self._openlane_file_templates + + @property + def command_templates(self) -> list[str]: + return self._openlane_command_templates + + @property + def _default_clk_name(self) -> str: + if self.default_clk is None: + raise AttributeError(f'Platform \'{type(self).__name__}\' does not define a default clock') + + res = self.lookup(self.default_clk) + + for resource, pin, _, _ in self._ports: + if resource == res: + return pin.i.name if res.ios[0].dir == 'i' else pin.o.name + + + raise ValueError(f'Platform \'{type(self).__name__}\' defined a default clock but has no matching resource') + + def build(self, *args, **kwargs): + self._build_dir = Path(kwargs.get('build_dir', 'build')).resolve() + return super().build(*args, **kwargs) + + def toolchain_prepare(self, fragment: Fragment, name: str, **kwargs) -> BuildPlan: + + # Propagate module ports for io placement + a_ports = kwargs.get('ports', None) + if a_ports is not None: + fragment._propagate_ports(ports = a_ports, all_undef_as_ports = False) + + return super().toolchain_prepare(fragment, name, **kwargs) diff --git a/torii/platform/asic/sky130.py b/torii/platform/asic/sky130.py new file mode 100644 index 000000000..be0fee9e3 --- /dev/null +++ b/torii/platform/asic/sky130.py @@ -0,0 +1,220 @@ +# SPDX-License-Identifier: BSD-3-Clause + +from .openlane import OpenLANEPlatform + +__all__ = ( + 'SKY130_PLATFORMS', + + 'SKY130A_PLATFORMS', + 'Sky130APlatform', + 'Sky130AHighDensityPlatform', + 'Sky130AHighSpeedPlatform', + 'Sky130AMediumSpeedPlatform', + 'Sky130ALowSpeedPlatform', + 'Sky130AHighDensityLowLeakagePlatform', + + 'SKY130B_PLATFORMS', + 'Sky130BPlatform', + 'Sky130BHighDensityPlatform', + 'Sky130BHighSpeedPlatform', + 'Sky130BMediumSpeedPlatform', + 'Sky130BLowSpeedPlatform', + 'Sky130BHighDensityLowLeakagePlatform', + +) + +# PDK Key: +# * FD - Foundry +# * SC - Standard Cell +# * HD - High Density +# * HDLL - High Density Low Leakage +# * LS/MS/HS - Low/Medium/High Speed + +class Sky130APlatform(OpenLANEPlatform): + '''OpenLANE - Sky130A PDK Platform + + .. warning:: + + **DO NOT** use any of the sky130A platforms unless you absolutely are sure + you know what you're doing, use the sky130B platforms instead! + + This is the base platform the specifies the the sky130A PDK. + + Don't use this platform directly unless you plan to override behavior, use one + of the specialized platforms instead: + + * :py:class:`Sky130AHighDensityPlatform` + * :py:class:`Sky130AHighSpeedPlatform` + * :py:class:`Sky130AMediumSpeedPlatform` + * :py:class:`Sky130ALowSpeedPlatform` + * :py:class:`Sky130AHighDensityLowLeakagePlatform` + + ''' # noqa: E101 + + pdk = 'sky130A' + +class Sky130AHighDensityPlatform(Sky130APlatform): + '''OpenLANE - Sky130A High Density + + .. warning:: + + **DO NOT** use any of the sky130A platforms unless you absolutely are sure + you know what you're doing, use the sky130B platforms instead! + + This platform is a specialization of the :py:class:`Sky130APlatform` that sets + the cell library to ``sky130_fd_sc_hd`` for the high-density standard cells. + + ''' + cell_library = 'sky130_fd_sc_hd' + +class Sky130AHighSpeedPlatform(Sky130APlatform): + '''OpenLANE - Sky130A High Speed + + .. warning:: + + **DO NOT** use any of the sky130A platforms unless you absolutely are sure + you know what you're doing, use the sky130B platforms instead! + + This platform is a specialization of the :py:class:`Sky130APlatform` that sets + the cell library to ``sky130_fd_sc_hs`` for the high speed standard cells. + + ''' + + cell_library = 'sky130_fd_sc_hs' + +class Sky130AMediumSpeedPlatform(Sky130APlatform): + '''OpenLANE - Sky130A Medium Speed + + .. warning:: + + **DO NOT** use any of the sky130A platforms unless you absolutely are sure + you know what you're doing, use the sky130B platforms instead! + + This platform is a specialization of the :py:class:`Sky130APlatform` that sets + the cell library to ``sky130_fd_sc_ms`` for the medium speed standard cells. + + ''' + + cell_library = 'sky130_fd_sc_ms' + +class Sky130ALowSpeedPlatform(Sky130APlatform): + '''OpenLANE - Sky130A Low Speed + + .. warning:: + + **DO NOT** use any of the sky130A platforms unless you absolutely are sure + you know what you're doing, use the sky130B platforms instead! + + This platform is a specialization of the :py:class:`Sky130APlatform` that sets + the cell library to ``sky130_fd_sc_ls`` for the low speed standard cells. + + ''' + + cell_library = 'sky130_fd_sc_ls' + +class Sky130AHighDensityLowLeakagePlatform(Sky130APlatform): + '''OpenLANE - Sky130A High Density Low Leakage + + .. warning:: + + **DO NOT** use any of the sky130A platforms unless you absolutely are sure + you know what you're doing, use the sky130B platforms instead! + + This platform is a specialization of the :py:class:`Sky130APlatform` that sets + the cell library to ``sky130_fd_sc_hdll`` for the high-density low-leakage standard cells. + + ''' + + cell_library = 'sky130_fd_sc_hdll' + +class Sky130BPlatform(OpenLANEPlatform): + '''OpenLANE - Sky130B PDK Platform + + This is the base platform the specifies the the sky130A PDK. + + Don't use this platform directly unless you plan to override behavior, use one + of the specialized platforms instead: + + * :py:class:`Sky130BHighDensityPlatform` + * :py:class:`Sky130BHighSpeedPlatform` + * :py:class:`Sky130BMediumSpeedPlatform` + * :py:class:`Sky130BLowSpeedPlatform` + * :py:class:`Sky130BHighDensityLowLeakagePlatform` + + ''' # noqa: E101 + + pdk = 'sky130B' + +class Sky130BHighDensityPlatform(Sky130BPlatform): + '''OpenLANE - Sky130B High Density + + This platform is a specialization of the :py:class:`Sky130BPlatform` that sets + the cell library to ``sky130_fd_sc_hd`` for the high-density standard cells. + + ''' + + cell_library = 'sky130_fd_sc_hd' + +class Sky130BHighSpeedPlatform(Sky130BPlatform): + '''OpenLANE - Sky130B High Speed + + + This platform is a specialization of the :py:class:`Sky130BPlatform` that sets + the cell library to ``sky130_fd_sc_hs`` for the high speed standard cells. + + ''' + + cell_library = 'sky130_fd_sc_hs' + +class Sky130BMediumSpeedPlatform(Sky130BPlatform): + '''OpenLANE - Sky130B Medium Speed + + + This platform is a specialization of the :py:class:`Sky130BPlatform` that sets + the cell library to ``sky130_fd_sc_ms`` for the medium speed standard cells. + + ''' + + cell_library = 'sky130_fd_sc_ms' + +class Sky130BLowSpeedPlatform(Sky130BPlatform): + '''OpenLANE - Sky130B Low Speed + + + This platform is a specialization of the :py:class:`Sky130BPlatform` that sets + the cell library to ``sky130_fd_sc_ls`` for the low speed standard cells. + + ''' + + cell_library = 'sky130_fd_sc_ls' + +class Sky130BHighDensityLowLeakagePlatform(Sky130BPlatform): + '''OpenLANE - Sky130B High Density Low Leakage + + This platform is a specialization of the :py:class:`Sky130BPlatform` that sets + the cell library to ``sky130_fd_sc_hdll`` for the high-density low-leakage standard cells. + + ''' + + cell_library = 'sky130_fd_sc_hdll' + +SKY130A_PLATFORMS = { + 'sky130_fd_sc_hd' : Sky130AHighDensityPlatform, + 'sky130_fd_sc_hs' : Sky130AHighSpeedPlatform, + 'sky130_fd_sc_ms' : Sky130AMediumSpeedPlatform, + 'sky130_fd_sc_ls' : Sky130ALowSpeedPlatform, + 'sky130_fd_sc_hdll': Sky130AHighDensityLowLeakagePlatform, +} + +SKY130B_PLATFORMS = { + 'sky130_fd_sc_hd' : Sky130BHighDensityPlatform, + 'sky130_fd_sc_hs' : Sky130BHighSpeedPlatform, + 'sky130_fd_sc_ms' : Sky130BMediumSpeedPlatform, + 'sky130_fd_sc_ls' : Sky130BLowSpeedPlatform, + 'sky130_fd_sc_hdll': Sky130BHighDensityLowLeakagePlatform, +} + +SKY130_PLATFORMS = { + 'sky130A': SKY130A_PLATFORMS, + 'sky130B': SKY130B_PLATFORMS, +} diff --git a/torii/platform/asic/sky90.py b/torii/platform/asic/sky90.py new file mode 100644 index 000000000..6464f4800 --- /dev/null +++ b/torii/platform/asic/sky90.py @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: BSD-3-Clause + +from .openlane import OpenLANEPlatform # noqa: F401