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

Initial ASIC flow platform support #5

Draft
wants to merge 12 commits into
base: main
Choose a base branch
from
Draft
79 changes: 79 additions & 0 deletions .github/workflows/asic.yaml
Original file line number Diff line number Diff line change
@@ -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 }}
15 changes: 1 addition & 14 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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]

Expand Down
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,40 @@ Torii can be used to target any FPGA or ASIC process that accepts behavioral Ver
</tbody>
</table>

> **Warning** ASIC Flow targets are super experimental
> and unstable at the moment.
> Please don't use these for production in any capacity.

<table>
<thead>
<tr>
<th rowspan="3">ASIC</th>
<th colspan="2">Toolchain</th>
</tr>
<tr></tr>
<tr>
<th>FOSS</th>
<th>Proprietary</th>
</tr>
</thead>
<tbody>
<tr>
<td>sky130</td>
<td rowspan="10">OpenLANE</td>
<td rowspan="10"></td>
</tr>
<tr></tr>
<tr>
<td>sky90</td>
</tr>
<tr></tr>
<tr>
<td>gf180mcu</td>
</tr>
</tbody>
</table>


## 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.
5 changes: 5 additions & 0 deletions docs/platforms/asic/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Torii ASIC Platforms

```{warning}
ASIC Support in Torii is not stable, use at your own risk
```
37 changes: 37 additions & 0 deletions examples/asic/alu.py
Original file line number Diff line number Diff line change
@@ -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])
38 changes: 38 additions & 0 deletions examples/asic/counter.py
Original file line number Diff line number Diff line change
@@ -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])
85 changes: 85 additions & 0 deletions examples/asic/fsm.py
Original file line number Diff line number Diff line change
@@ -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])
14 changes: 11 additions & 3 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -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))

Expand All @@ -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',
Expand Down
18 changes: 18 additions & 0 deletions torii/platform/asic/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# SPDX-License-Identifier: BSD-3-Clause

from .sky130 import (
Sky130BHighDensityPlatform,
Sky130BHighSpeedPlatform,
Sky130BMediumSpeedPlatform,
Sky130BLowSpeedPlatform,
Sky130BHighDensityLowLeakagePlatform,
)


__all__ = (
'Sky130BHighDensityPlatform',
'Sky130BHighSpeedPlatform',
'Sky130BMediumSpeedPlatform',
'Sky130BLowSpeedPlatform',
'Sky130BHighDensityLowLeakagePlatform',
)
13 changes: 13 additions & 0 deletions torii/platform/asic/efabless_caravel.py
Original file line number Diff line number Diff line change
@@ -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__()
3 changes: 3 additions & 0 deletions torii/platform/asic/gf180mcu.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# SPDX-License-Identifier: BSD-3-Clause

from .openlane import OpenLANEPlatform # noqa: F401
Loading
Loading