Skip to content
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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ jobs:
with:
python-version: "3.12"
cache: pip
- run: python -m pip install 'mkdocs>=1.6'
- run: python -m pip install -r requirements-docs.txt
- run: mkdocs build --strict

package:
Expand Down
120 changes: 120 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
name: Documentation

on:
pull_request:
paths:
- "docs/**"
- "README*"
- "CONTRIBUTING.md"
- "mkdocs.yml"
- "requirements-docs.txt"
- "pyproject.toml"
- "scripts/docs.py"
- "scripts/sync_wiki.py"
- "scripts/tests/**"
- ".github/workflows/docs.yml"
push:
branches: [main, "docs/**"]
paths:
- "docs/**"
- "README*"
- "CONTRIBUTING.md"
- "mkdocs.yml"
- "requirements-docs.txt"
- "pyproject.toml"
- "scripts/docs.py"
- "scripts/sync_wiki.py"
- "scripts/tests/**"
- ".github/workflows/docs.yml"
workflow_dispatch:

permissions:
contents: read

concurrency:
group: documentation-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}

jobs:
documentation:
runs-on: ubuntu-24.04
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip
cache-dependency-path: requirements-docs.txt
- name: Install documentation tools
run: python -m pip install -r requirements-docs.txt
- name: Test documentation tooling
run: python -m unittest discover -s scripts/tests -v
- name: Check documentation links
run: python scripts/docs.py check
- name: Build documentation site
run: python -m mkdocs build --strict --site-dir build/docs-site
- name: Export Wiki pages
run: python scripts/docs.py wiki --output build/wiki-export
- name: Upload documentation preview
uses: actions/upload-artifact@v4
with:
name: toffee-documentation
if-no-files-found: error
path: |
build/docs-site
build/wiki-export

sync-wiki:
name: Sync GitHub Wiki
needs: [documentation]
if: >-
github.repository == 'XS-MLVP/toffee' &&
github.ref == 'refs/heads/main' &&
(github.event_name == 'push' || github.event_name == 'workflow_dispatch')
runs-on: ubuntu-24.04
timeout-minutes: 10
permissions:
contents: write
concurrency:
group: wiki-sync
cancel-in-progress: false
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- uses: actions/download-artifact@v4
with:
name: toffee-documentation
path: build
# GitHub requires an initial page created through the Wiki web UI.
# Specifying ref avoids querying the REST API for the separate Wiki repo.
- name: Checkout initialized Wiki
uses: actions/checkout@v4
with:
repository: ${{ github.repository }}.wiki
ref: master
path: wiki-checkout
- name: Sync generated pages and push changes
env:
SOURCE_SHA: ${{ github.sha }}
run: |
set -euo pipefail
git fetch --no-tags --depth=1 origin main
if ! git diff --quiet "$SOURCE_SHA" FETCH_HEAD -- docs/ "README*" CONTRIBUTING.md mkdocs.yml requirements-docs.txt pyproject.toml scripts/docs.py scripts/sync_wiki.py scripts/tests/ .github/workflows/docs.yml; then
echo "Documentation has advanced; skipping this outdated export."
exit 0
fi
python scripts/sync_wiki.py --export build/wiki-export --checkout wiki-checkout
git -C wiki-checkout add --all
if git -C wiki-checkout diff --cached --quiet; then
echo "Wiki is already up to date."
exit 0
fi
git -C wiki-checkout config user.name 'github-actions[bot]'
git -C wiki-checkout config user.email '41898282+github-actions[bot]@users.noreply.github.com'
git -C wiki-checkout commit -m "Sync documentation from $SOURCE_SHA"
git -C wiki-checkout push origin HEAD:master
58 changes: 51 additions & 7 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,67 @@ Toffee 负责 Python API、仿真调度、验证组件和报告。

## 文档按读者目的组织

文档采用 [Diátaxis](https://diataxis.fr/) 的四类划分:
中文源文档放在 `docs/zh/`,英文放在 `docs/en/`,相对路径一一对应。新增或修改
公共能力时,同一个 PR 更新两种语言;共享的可执行代码块保持一致,避免示例漂移。
导航使用语言无关路径,英文标题配置在 `mkdocs.yml` 的 `nav_translations` 中。
站点默认中文,提供 English 切换;缺失翻译不回退到中文,检查会直接失败。

文档采用 [Diátaxis](https://diataxis.fr/) 的四类划分;下表以中文路径为例:

| 类型 | 位置 | 写作要求 |
| --- | --- | --- |
| 教程 | `docs/getting-started/` | 带读者完成可复现的练习,给出命令与预期结果;逐步引入概念,减少分支选择 |
| 操作指南 | `docs/guides/` | 开头说明目标和前提,围绕实际任务给步骤、验证方法和常见失败处理 |
| 参考 | `docs/reference/` | 准确列出签名、默认值、单位、返回值、异常与限制;与实现逐项核对 |
| 原理说明 | `docs/explanation/` | 解释原因、边界和取舍,通过具体场景建立概念之间的联系 |
| 教程 | `docs/zh/getting-started/` | 带读者完成可复现的练习,给出命令与预期结果;逐步引入概念,减少分支选择 |
| 操作指南 | `docs/zh/guides/` | 开头说明目标和前提,围绕实际任务给步骤、验证方法和常见失败处理 |
| 参考 | `docs/zh/reference/` | 准确列出签名、默认值、单位、返回值、异常与限制;与实现逐项核对 |
| 原理说明 | `docs/zh/explanation/` | 解释原因、边界和取舍,通过具体场景建立概念之间的联系 |

一页主要解决一种阅读需求;需要其他类型的内容时链接过去,避免在操作步骤中展开长篇
原理,或在教程中罗列所有参数。已有页面混合多种内容时逐步拆分,并尽量保留旧地址。
例如,配置步骤留在 Execution 指南,默认值放在 Execution 参考,调度原因放在原理说明。

新增页面须接入 `mkdocs.yml` 和相应目录入口。检查相对链接与页内锚点,
运行 `python3 -m pytest -q tests/integration/test_documentation.py` 和 `mkdocs build --strict`。
运行 `python3 scripts/docs.py check`、
`python3 -m pytest -q tests/integration/test_documentation.py tests/integration/test_quickstart_tutorial.py`
和 `mkdocs build --strict`。
新增可运行示例时还要实际执行;已有覆盖模型片段由文档测试校验。

## Wiki 自动同步

Wiki 的内容来自 `main` 的 `docs/zh/` 和 `docs/en/`,导航来自 `mkdocs.yml`。
首页提供语言选择,页面名使用 `zh-` / `en-` 前缀,每页链接对应的另一语言版本。
只需编辑这些源文件;功能与对应的双语文档应在同一个 PR 中提交。
**Documentation** 工作流校验链接、构建网站,导出页面及侧边栏,并上传预览产物。
文档修改进入 `main` 并通过检查后,会同步到 `toffee.wiki.git`;PR 和其他分支只生成预览。
Legacy `master` 不参与同步。Wiki 工作流独立于软件包发布检查,避免扩大其写权限。

首次启用时,须在仓库设置中开启 Wiki,并在 GitHub Wiki 网页创建一次首页。
同步使用自带的 `GITHUB_TOKEN`,只有发布任务拥有 `contents: write`,无需额外 secret。
失败后可在 Actions 中选择 `main` 手动运行 **Documentation**。新文档已提交时,旧导出会跳过发布。

本地验证和导出不需要安装原生依赖:

```bash
python3 -m pip install -r requirements-docs.txt
python3 -m unittest discover -s scripts/tests -v
python3 scripts/docs.py check
python3 -m mkdocs build --strict
python3 scripts/docs.py wiki --output build/wiki-preview
```

导出目录须为空。页面、源码和图片链接转换为绝对 URL,代码示例保持原样。
`manifest.json` 记录每个生成页面的 SHA-256。同步会更新生成页面,首次运行时替换初始化
首页、侧边栏和页脚;其他手工内容会保留,同名冲突会报错。过期页面只有在仍符合旧清单时
才被删除,存在手工改动时停止供检查。内容不变时不创建提交,推送不会强制覆盖历史。
请将生成页面的修改提交到主仓库,避免下一次自动同步覆盖网页上的手工编辑。

本地检查同步差异时,先克隆已初始化的 Wiki,再执行:

```bash
git clone https://github.com/XS-MLVP/toffee.wiki.git build/wiki-checkout
python3 scripts/sync_wiki.py --export build/wiki-preview --checkout build/wiki-checkout
git -C build/wiki-checkout diff
```

## 提交前检查

先准备 `uc-xcomm>=1.1,<2`,再安装开发依赖。开发跨仓库未发布修改时,
Expand Down Expand Up @@ -80,7 +124,7 @@ BUILD_XSPCOMM_SWIG=python XSPCOMM_BUILD_WHEEL=1 \

版本号由 Git tag 和 setuptools-scm 生成,不在源码中另写一份。
针对 main 的 PR 需选择一个版本标签:`release:patch`、`release:minor` 或 `release:major`。
具体选择和发布失败后的处理见[版本与发布](docs/guides/versioning-and-releases.md)。
具体选择和发布失败后的处理见[版本与发布](docs/zh/guides/versioning-and-releases.md)。

发布检查包括原生回归、严格文档构建、源码包重建和隔离安装。
验证通过后发布的是同一组已检查产物,不另行构建一份替代。
2 changes: 1 addition & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
include LICENSE README.md CONTRIBUTING.md pyproject.toml mkdocs.yml
include LICENSE README.md README.en.md CONTRIBUTING.md pyproject.toml mkdocs.yml requirements-docs.txt
include .github/native-dependencies.json
recursive-include src *.py *.html *.css
recursive-include scripts *.py
Expand Down
100 changes: 100 additions & 0 deletions README.en.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Toffee

[中文](https://github.com/XS-MLVP/toffee/blob/main/README.md) · English

[![PyPI](https://img.shields.io/pypi/v/uc-toffee?style=flat-square&logo=pypi&logoColor=white)](https://pypi.org/project/uc-toffee/)
[![Python](https://img.shields.io/badge/python-3.11%20%7C%203.12-blue?style=flat-square&logo=python&logoColor=white)](https://github.com/XS-MLVP/toffee/blob/main/docs/en/getting-started/installation.md)
[![CI](https://img.shields.io/github/actions/workflow/status/XS-MLVP/toffee/ci.yml?branch=main&style=flat-square&label=CI&logo=github)](https://github.com/XS-MLVP/toffee/actions/workflows/ci.yml?query=branch%3Amain)
[![License](https://img.shields.io/badge/license-MulanPSL--2.0-blue?style=flat-square)](https://github.com/XS-MLVP/toffee/blob/main/LICENSE)
[![Docs](https://img.shields.io/badge/docs-Guide-0A7EA4?style=flat-square)](https://github.com/XS-MLVP/toffee/blob/main/docs/en/index.md)
[![GitHub Stars](https://img.shields.io/github/stars/XS-MLVP/toffee?style=social)](https://github.com/XS-MLVP/toffee/tree/main)

Toffee is a Python hardware verification framework. Describe input timing and condition waits with
`async` / `await`, run tests with pytest, and build verification environments with reference models,
checking, and coverage.

- **Clocks and events:** wait for clock edges, signal conditions, and multi-cycle events, with
supported conditions compiled for native evaluation.
- **Driving and checking:** organize reusable Drivers, Monitors, and Agents; check ordered or
reordered responses with Scoreboard.
- **Coverage and regressions:** define functional, cross, and temporal coverage, then aggregate
functional and native coverage after parallel regressions.

## Quick start

Requires **Python 3.11+**. The PyPI distribution is `uc-toffee`, imported as `toffee`; dependency
`uc-xcomm` supplies native bindings. Install with `python3 -m pip install "uc-toffee[runner]"`.
To run the repository examples, create an environment and install from source at the repository root:

```bash
python3 -m venv .venv
source .venv/bin/activate
python3 -m pip install -e '.[test]'
```

This test uses the included 8-bit accumulator model and needs no RTL simulator. It supplies 3,
waits one clock cycle, and checks the accumulated result and idle behavior:

```python
import pytest

from toffee import ClockCycles, Execution
from examples.getting_started.toy_dut import TutorialDut


@pytest.mark.asyncio
async def test_one_input_and_idle():
dut = TutorialDut()
try:
async with Execution(dut.backend):
assert dut.total.U() == 0
dut.operand.Set(3)
dut.enable.Set(1)
await ClockCycles(dut.clock, 1)
dut.enable.Set(0)
assert dut.total.U() == 3

await ClockCycles(dut.clock, 2)
assert dut.total.U() == 3
finally:
dut.close()
```

The test is already in the [example file](https://github.com/XS-MLVP/toffee/blob/main/examples/getting_started/test_accumulator.py).
Run it directly:

```bash
python3 -m pytest -q examples/getting_started/test_accumulator.py::test_one_input_and_idle
```

Expect `1 passed`. Continue with the [accumulator tutorial](https://github.com/XS-MLVP/toffee/blob/main/docs/en/getting-started/index.md)
to add boundary tests, Drivers, Monitors, reference models, and coverage.

## Use Toffee in a project

For real RTL, use a Picker-generated DUT Python package and connect its xspcomm clock/signals
through `XCommClockBackend`. See [real DUT integration](https://github.com/XS-MLVP/toffee/blob/main/docs/en/getting-started/native-and-next.md)
for preparation and dependencies.

Use `toffee run` to execute larger regressions in parallel and aggregate coverage. For example:

```bash
toffee run examples/getting_started --workers 4
```

The terminal prints the run's artifact directory, including `coverage.html` when coverage data
exists. Replace the example path with your project's test directory. See the
[regression guide](https://github.com/XS-MLVP/toffee/blob/main/docs/en/guides/runner.md) for options.

## Documentation

- [Tutorials](https://github.com/XS-MLVP/toffee/blob/main/docs/en/getting-started/index.md): from one assertion to a complete environment.
- [How-to guides](https://github.com/XS-MLVP/toffee/blob/main/docs/en/guides/index.md): connect DUTs, organize components, collect coverage, and run regressions.
- [Reference](https://github.com/XS-MLVP/toffee/blob/main/docs/en/reference/index.md): APIs, CLI options, and behavioral limits.
- [Explanation](https://github.com/XS-MLVP/toffee/blob/main/docs/en/explanation/index.md): scheduling, ownership, and coverage interpretation.
- [Runnable examples](https://github.com/XS-MLVP/toffee/blob/main/docs/en/examples.md) · [Contributing](https://github.com/XS-MLVP/toffee/blob/main/CONTRIBUTING.md)

## Toffee Legacy

Legacy Toffee remains on the [`master` branch](https://github.com/XS-MLVP/toffee/tree/master).
The current version is a **breaking change** and is incompatible with the Toffee Legacy API.
22 changes: 12 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
# Toffee

中文 · [English](https://github.com/XS-MLVP/toffee/blob/main/README.en.md)

[![PyPI](https://img.shields.io/pypi/v/uc-toffee?style=flat-square&logo=pypi&logoColor=white)](https://pypi.org/project/uc-toffee/)
[![Python](https://img.shields.io/badge/python-3.11%20%7C%203.12-blue?style=flat-square&logo=python&logoColor=white)](https://github.com/XS-MLVP/toffee/blob/main/docs/getting-started/installation.md)
[![Python](https://img.shields.io/badge/python-3.11%20%7C%203.12-blue?style=flat-square&logo=python&logoColor=white)](https://github.com/XS-MLVP/toffee/blob/main/docs/zh/getting-started/installation.md)
[![CI](https://img.shields.io/github/actions/workflow/status/XS-MLVP/toffee/ci.yml?branch=main&style=flat-square&label=CI&logo=github)](https://github.com/XS-MLVP/toffee/actions/workflows/ci.yml?query=branch%3Amain)
[![License](https://img.shields.io/badge/license-MulanPSL--2.0-blue?style=flat-square)](https://github.com/XS-MLVP/toffee/blob/main/LICENSE)
[![Docs](https://img.shields.io/badge/docs-Guide-0A7EA4?style=flat-square)](https://github.com/XS-MLVP/toffee/blob/main/docs/index.md)
[![Docs](https://img.shields.io/badge/docs-Guide-0A7EA4?style=flat-square)](https://github.com/XS-MLVP/toffee/blob/main/docs/zh/index.md)
[![GitHub Stars](https://img.shields.io/github/stars/XS-MLVP/toffee?style=social)](https://github.com/XS-MLVP/toffee/tree/main)

Toffee 是一个 Python 硬件验证框架。用 `async` / `await` 描述输入时序与条件等待,
Expand Down Expand Up @@ -60,13 +62,13 @@ async def test_one_input_and_idle():
python3 -m pytest -q examples/getting_started/test_accumulator.py::test_one_input_and_idle
```

预期得到 `1 passed`。继续阅读[累加器教程](https://github.com/XS-MLVP/toffee/blob/main/docs/getting-started/index.md),
预期得到 `1 passed`。继续阅读[累加器教程](https://github.com/XS-MLVP/toffee/blob/main/docs/zh/getting-started/index.md),
逐步加入边界测试、Driver、Monitor、参考模型与覆盖率。

## 用于项目验证

接入真实 RTL 时,使用 Picker 生成的 DUT Python 包,通过 `XCommClockBackend`
连接 xspcomm 的时钟与信号。具体准备和依赖要求见[真实 DUT 接入指南](https://github.com/XS-MLVP/toffee/blob/main/docs/getting-started/native-and-next.md)。
连接 xspcomm 的时钟与信号。具体准备和依赖要求见[真实 DUT 接入指南](https://github.com/XS-MLVP/toffee/blob/main/docs/zh/getting-started/native-and-next.md)。

测试增多后,用 `toffee run` 并行执行并汇总覆盖率。例如,运行整个入门示例目录:

Expand All @@ -75,15 +77,15 @@ toffee run examples/getting_started --workers 4
```

终端会显示本次运行的产物目录;有覆盖数据时会生成 `coverage.html`。
将示例路径换成项目测试目录即可运行自己的回归,更多选项见[回归运行指南](https://github.com/XS-MLVP/toffee/blob/main/docs/guides/runner.md)。
将示例路径换成项目测试目录即可运行自己的回归,更多选项见[回归运行指南](https://github.com/XS-MLVP/toffee/blob/main/docs/zh/guides/runner.md)。

## 文档

- [入门教程](https://github.com/XS-MLVP/toffee/blob/main/docs/getting-started/index.md):从一条断言到完整的验证环境。
- [操作指南](https://github.com/XS-MLVP/toffee/blob/main/docs/guides/index.md):接入 DUT、组织组件、采集覆盖率和运行回归。
- [接口参考](https://github.com/XS-MLVP/toffee/blob/main/docs/reference/index.md):API、命令行参数和行为限制。
- [原理说明](https://github.com/XS-MLVP/toffee/blob/main/docs/explanation/index.md):仿真调度、资源归属与覆盖率含义。
- [可运行示例](https://github.com/XS-MLVP/toffee/blob/main/docs/examples.md) · [参与开发](https://github.com/XS-MLVP/toffee/blob/main/CONTRIBUTING.md)
- [入门教程](https://github.com/XS-MLVP/toffee/blob/main/docs/zh/getting-started/index.md):从一条断言到完整的验证环境。
- [操作指南](https://github.com/XS-MLVP/toffee/blob/main/docs/zh/guides/index.md):接入 DUT、组织组件、采集覆盖率和运行回归。
- [接口参考](https://github.com/XS-MLVP/toffee/blob/main/docs/zh/reference/index.md):API、命令行参数和行为限制。
- [原理说明](https://github.com/XS-MLVP/toffee/blob/main/docs/zh/explanation/index.md):仿真调度、资源归属与覆盖率含义。
- [可运行示例](https://github.com/XS-MLVP/toffee/blob/main/docs/zh/examples.md) · [参与开发](https://github.com/XS-MLVP/toffee/blob/main/CONTRIBUTING.md)

## Toffee Legacy

Expand Down
Loading
Loading