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
20 changes: 18 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ BOOTLOAD_MONITOR_ARG ?= --monitor
FIRMWARE_PROFILE ?= baremetal
FIRMWARE_RUNTIME ?=
FIRMWARE_DEBUG ?= none
FIRMWARE_ACCEL ?= none
FIRMWARE_MAIN ?= $(REPO_ROOT)/firmware/apps/baremetal/soc_selftest.c
GDB_STUB_MAIN ?= $(REPO_ROOT)/firmware/apps/baremetal/gdb_stub_smoke.c
APP ?=
Expand Down Expand Up @@ -92,7 +93,7 @@ SELECTED_FIRMWARE_PROFILE := $(if $(strip $(APP)),,$(FIRMWARE_PROFILE))
SELECTED_FIRMWARE_RUNTIME := $(if $(strip $(APP)),$(APP_RUNTIME),$(FIRMWARE_RUNTIME))
SELECTED_FIRMWARE_MAIN := $(if $(strip $(APP)),$(APP_SOURCE),$(FIRMWARE_MAIN))

.PHONY: help check-env firmware firmware-load firmware-debug timer-irq-smoke timer-irq-load freertos-smoke freertos-queue freertos-acceptance freertos-load freertos-acceptance-load bootload gdb-stub-load gdb-stub-debug boot-image-test-build boot-image-test-load bad-apple-build bad-apple-load bad-apple-full-build bad-apple-full-preview bad-apple-source-audio-preview bad-apple-compact-midi-preview bad-apple-full-load bad-apple-window-build bad-apple-window-preview bad-apple-window-load rtl-syntax sim test-probe test-platform test-soc test-smoke test-freertos test-dual-core test-all ci ci-full perf benchmark board-benchmark ise-export
.PHONY: help check-env firmware firmware-load firmware-debug dot4-bench dot4-load timer-irq-smoke timer-irq-load freertos-smoke freertos-queue freertos-acceptance freertos-load freertos-acceptance-load bootload gdb-stub-load gdb-stub-debug boot-image-test-build boot-image-test-load bad-apple-build bad-apple-load bad-apple-full-build bad-apple-full-preview bad-apple-source-audio-preview bad-apple-compact-midi-preview bad-apple-full-load bad-apple-window-build bad-apple-window-preview bad-apple-window-load rtl-syntax sim test-probe test-platform test-soc test-smoke test-freertos test-dual-core test-all ci ci-full perf benchmark board-benchmark ise-export

help:
@echo "常用目标:"
Expand All @@ -101,6 +102,8 @@ help:
@echo " make firmware APP=baremetal/hello.c 按 apps 目录构建用户程序"
@echo " make firmware-load APP=... PORT=COM8 构建、上传并监视用户程序"
@echo " make firmware-debug APP=baremetal/... PORT=COM8 启动 Windows GDB"
@echo " make dot4-bench 仿真比较 RV32I scalar 与 custom-0 DOT4"
@echo " make dot4-load PORT=COM8 构建并上传 DarkRISCV DOT4 benchmark"
@echo " make firmware FIRMWARE_OUT=... 构建到指定输出前缀"
@echo " make timer-irq-smoke 构建 DarkRISCV timer IRQ 专用镜像"
@echo " make timer-irq-load PORT=COM8 构建、上传并监视 timer IRQ 验收镜像"
Expand Down Expand Up @@ -137,14 +140,16 @@ help:
@echo " make perf / make benchmark 跑完整双核 benchmark,并生成日志、表格和环境快照"
@echo " make board-benchmark PORT=COM9 BOOTLOAD_BAUD=115200 上板运行性能测试"
@echo " make ise-export ISE_TARGET=minisoc 导出 ISE 工程所需文件到新目录"
@echo " make ise-export ISE_TARGET=minisoc_dot4_dark 导出 DOT4 ISE/上板包"

check-env:
"$(CHECK_ENV)"

firmware:
FIRMWARE_PROFILE="$(SELECTED_FIRMWARE_PROFILE)" \
FIRMWARE_RUNTIME="$(SELECTED_FIRMWARE_RUNTIME)" \
FIRMWARE_DEBUG="$(FIRMWARE_DEBUG)" \
FIRMWARE_DEBUG="$(FIRMWARE_DEBUG)" \
FIRMWARE_ACCEL="$(FIRMWARE_ACCEL)" \
FIRMWARE_MAIN="$(SELECTED_FIRMWARE_MAIN)" \
"$(BUILD_FIRMWARE)"

Expand All @@ -162,6 +167,16 @@ firmware-debug:
$(if $(filter baremetal,$(APP_RUNTIME)),,$(error 当前 GDB 调试尚不支持 $(APP_RUNTIME) 应用))
@$(MAKE) gdb-stub-debug PORT="$(PORT)" GDB_STUB_MAIN="$(APP_SOURCE)"

dot4-bench:
"$(REPO_ROOT)/scripts/test_dot4_benchmark.sh"

dot4-load:
$(if $(PORT),,$(error dot4-load 需要 PORT,例如 PORT=COM8))
@$(MAKE) bootload PORT="$(PORT)" \
FIRMWARE_PROFILE=baremetal \
FIRMWARE_ACCEL=dot4 \
FIRMWARE_MAIN="$(REPO_ROOT)/firmware/apps/baremetal/benchmarks/dot4_bench.c"

timer-irq-smoke:
FIRMWARE_PROFILE=dark_irq \
FIRMWARE_MAIN="$(REPO_ROOT)/firmware/apps/irq/timer_irq_smoke.c" \
Expand Down Expand Up @@ -196,6 +211,7 @@ bootload:
@FIRMWARE_PROFILE="$(FIRMWARE_PROFILE)" \
FIRMWARE_RUNTIME="$(FIRMWARE_RUNTIME)" \
FIRMWARE_DEBUG="$(FIRMWARE_DEBUG)" \
FIRMWARE_ACCEL="$(FIRMWARE_ACCEL)" \
FIRMWARE_MAIN="$(FIRMWARE_MAIN)" \
FIRMWARE_OUT="$(BOOTLOAD_FIRMWARE_OUT)" \
"$(BUILD_FIRMWARE)"
Expand Down
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,19 @@ TecPlusRV 是一个面向 TEC-PLUS Spartan-6 XC6SLX9-2FTG256 平台的 RISC-V So
- 从 SDRAM 取指或启动的执行路径
- ISE 工程文件或 bitstream

## DarkRISCV custom-0 DOT4

DarkRISCV profile 实现了一条非标准 `dot4.s8 rd, rs1, rs2` 指令:两个源寄存器
各打包四个 signed INT8,结果为四组乘积之和。它不是完整 SIMD/Vector 扩展,
PicoRV32 也不会执行这条指令。详细编码、验证边界和 ISE/上板步骤见
[`docs/DOT4_CUSTOM_ISA.md`](docs/DOT4_CUSTOM_ISA.md)。

```bash
make dot4-bench
make ise-export ISE_TARGET=minisoc_dot4_dark
make dot4-load PORT=COM8

@Liophis Liophis Jul 13, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test1

```

## 仓库结构

- `rtl/probe/`:早期上板探针顶层
Expand Down
18 changes: 18 additions & 0 deletions docs/BENCHMARKS.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,21 @@ BENCHMARK_RUN_ID=after-change make perf
## 已归档的 #19 基线

2026-07-10 的完整仿真样本已固定在 [`results/issue19-2026-07-10/`](../results/issue19-2026-07-10/),课程化的结论见 [`reports/issue19-performance-summary.md`](../reports/issue19-performance-summary.md)。该样本是 Icarus 仿真基线,不是板级 benchmark;后续优化和上板 PPA 的记录方式见 [`docs/FUTURE_PERFORMANCE_PLAN.md`](FUTURE_PERFORMANCE_PLAN.md)。

## DarkRISCV custom-0 DOT4 microbenchmark

```bash
make dot4-bench
```

该命令只运行 DarkRISCV,比较相同 packed INT8 输入下的纯 RV32I scalar kernel 与
`dot4.s8`。脚本会自动检查 checksum 一致,并要求 custom 的 `cycles` 和 `instret`
均低于 scalar。2026-07-13 当前 Icarus 样本为:

| 模式 | cycles | instret | checksum |
| --- | ---: | ---: | --- |
| RV32I scalar | 694296 | 242718 | `0x00000170` |
| custom-0 DOT4 | 25752 | 6718 | `0x00000170` |

在该固定 workload 下 cycle speedup 为 `26.96x`。这是 RTL 仿真相对结果;实际吞吐、
DSP/LUT 代价与 Fmax 必须用 ISE Map/PAR/Timing Report 和真实上板日志重新确认。
101 changes: 101 additions & 0 deletions docs/DOT4_CUSTOM_ISA.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# DarkRISCV custom-0 DOT4 扩展

## 指令语义

`dot4.s8 rd, rs1, rs2` 使用 RISC-V `custom-0` opcode,只在 TecPlusRV 的
DarkRISCV profile 中实现:

```text
opcode = 0001011
funct3 = 000
funct7 = 0000000

rd = signed(rs1[7:0]) * signed(rs2[7:0])
+ signed(rs1[15:8]) * signed(rs2[15:8])
+ signed(rs1[23:16]) * signed(rs2[23:16])
+ signed(rs1[31:24]) * signed(rs2[31:24])
```

结果写回 signed 32-bit。它是一条 packed INT8、SIMD-style dot-product 指令,
不是完整 RISC-V Vector/SIMD 扩展,也不是带旧 `rd` 输入的 MAC。其他
`custom-0` 编码必须触发 illegal-instruction trap。

## 硬件路径

```text
DarkRISCV decode/execute
-> CPR_REQ + CPR_PC + rs1/rs2
-> rtl/accel/dot4_int8.v
-> CPR_ACK + result
-> register file rd
```

`CPR_PC` 是 transaction tag。协处理器将注册结果与发起指令 PC 绑定:流水线因
`CPR_ACK` 继续后,如果下一条仍是 DOT4,PC 改变会立即撤销旧 ACK,从而避免同一条
重复执行或相邻指令错误复用旧结果。等待期间 interrupt 延后到完整指令边界。

软件 ABI 位于 `firmware/accel/dot4.S`:

```c
int dot4_s8(unsigned int packed_a, unsigned int packed_b);
```

默认 firmware 不包含该非标准指令;只有显式设置 `FIRMWARE_ACCEL=dot4` 才链接包装函数。

## 自动验证

```bash
./sim/run_sim.sh dot4_int8
./sim/run_sim.sh darkriscv_dot4
make dot4-bench
python3 scripts/test_runner.py run-suite rv32i_safe --keep-going
python3 scripts/test_runner.py run-suite rv32mi_dark --keep-going
```

覆盖范围包括 signed lane 边界、相邻请求、reset、结果写回、`rd=x0`、illegal
custom-0、协处理器 stall 中的 timer IRQ,以及 scalar/custom checksum 和性能方向。

## ISE 与上板人工 Gate

```bash
make ise-export ISE_TARGET=minisoc_dot4_dark
make dot4-load PORT=COM8
```

阶段性人工记录见 [`reports/dot4-board-validation.md`](../reports/dot4-board-validation.md)。
该报告已经记录 Map 资源、真实开发板 UART benchmark、50 MHz timing 和
`OVERMAPPED` 搜索结果;XST report 已出现 `Unit <u_dot4>`,`g_darkriscv`
层级名未直接检索到,当前以 `CPU_IMPL=1`、DSP48A1 使用量与 UART PASS
作为间接证据。

本分支的面积基线是共同祖先 `35968e6` 上的 `minisoc_dark`,不是当前分支的
`minisoc_dark`:当前分支已经全局接入 DOT4,拿它作对照会把加速器也综合进去。本地已
准备两份脱离源码树仍可独立 elaboration 的导出包:

```text
build/ise-export/minisoc_dark_baseline-35968e6
build/ise-export/minisoc_dot4_dark-final
```

两份工程都设置相同的 `CPU_IMPL=1`、`BOOTLOADER_ENABLE=1`、
`VGA_TEXT_ENABLE=0`,使用同一器件、ISE 设置和 50 MHz 约束。报告至少并排记录:

| 配置 | Slice | LUT | FF | RAMB16 | DSP48A1 | 50 MHz slack |
| --- | ---: | ---: | ---: | ---: | ---: | ---: |
| DarkRISCV baseline (`35968e6`) | 待填写 | 待填写 | 待填写 | 待填写 | 待填写 | 待填写 |
| DarkRISCV + DOT4(报告中记录实际 feature HEAD) | 待填写 | 待填写 | 待填写 | 待填写 | 待填写 | 待填写 |
| 增量 | 待计算 | 待计算 | 待计算 | 待计算 | 待计算 | — |

DSP48A1 数量用于解释实现方式,不作为功能正确性的硬性条件:XST 可能把四个 signed
8x8 乘法映射到 DSP,也可能使用 LUT。无论采用哪种映射,都必须确认 `u_dot4` 未被
trim、Map 未 overmap 且 post-route slack 为正。

ISE 中设置 `CPU_IMPL=1`、`BOOTLOADER_ENABLE=1`、`VGA_TEXT_ENABLE=0`,并保存:

1. XST/Map 报告:无 `OVERMAPPED`,记录 Slice/LUT/FF 与 DSP48A1 数量;
2. PAR/Timing Report:50 MHz post-route slack 必须为正;
3. hierarchy:`g_darkriscv` 和 `u_dot4` 未被 trim;
4. UART 原始日志:scalar/custom checksum 相同,custom cycles/instret 更低。

本地 Icarus 不能证明 DSP 推断、板级 Fmax 或真实上板行为,因此在收到这些报告前,
文档只能声明“仿真通过”,不能声明硬件验收完成。
2 changes: 1 addition & 1 deletion docs/PROJECT_SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ TecPlusRV 对应北京邮电大学《项目式课程阶段 2》题目 B:基于

## 拓展目标

- 增加轻量级加速器,例如 popcount、Hamming distance、DOT4 INT8
- 已实现 DarkRISCV custom-0 `DOT4 INT8` 指令;后续可增加 MMIO frontend,比较接口开销
- 增加更丰富的调试/可观测机制
- 尝试 Flash / EEPROM 相关启动或配置功能
- 如果时间允许,再增加显示类可观测外设
Expand Down
85 changes: 85 additions & 0 deletions docs/superpowers/plans/2026-07-13-darkriscv-custom-dot4.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# DarkRISCV custom-0 DOT4 Implementation Plan

> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.

**Goal:** 为 DarkRISCV 增加 signed INT8 `dot4.s8` custom-0 指令,并以 RTL、core、MiniSoC benchmark、官方 ISA 回归和 ISE/上板 Gate 验证。

**Architecture:** 独立 DOT4 模块通过 DarkRISCV `CPR_*` 接口接入,`CPR_PC` 绑定 transaction;软件用独立汇编 ABI 调用,默认 RV32I firmware 不包含自定义指令。

**Tech Stack:** Verilog-2001、Icarus Verilog、RV32I assembly、riscv64-unknown-elf GCC/binutils、TecPlusRV test runner、ISE 14.7。

## Global Constraints

- 所有开发者文本使用中文,保留常用英文术语。
- 第一版仅支持 DarkRISCV,MMIO、PicoRV32 PCPI、完整 SIMD/Vector 和浮点不在范围内。
- 指令为 signed INT8 纯点积,lane 0=`[7:0]`。
- 每项行为先观察失败测试,再写最小实现。
- ISE/PAR 和上板属于人工 Gate,不能用 Icarus 替代。

---

### Task 1: DOT4 计算与 transaction 握手

**Files:**
- Create: `rtl/accel/dot4_int8.v`
- Create: `sim/tb_dot4_int8.v`
- Modify: `sim/run_sim.sh`
- Modify: `scripts/rtl_syntax_case.sh`
- Modify: `scripts/test_catalog.json`
- Modify: `rtl/files.f`

**Interfaces:** `req/tag/rs1/rs2 -> ack/result`。

- [x] 写缺少 module 时失败的 testbench。
- [x] 实现 signed 四路乘法、18-bit 求和与 32-bit 符号扩展。
- [x] 用 PC tag 覆盖同一请求保持和相邻请求连续为高。
- [x] 运行 `./sim/run_sim.sh dot4_int8` 与 syntax case。

### Task 2: DarkRISCV custom-0 接入

**Files:**
- Create: `firmware/tests/darkriscv_dot4.S`
- Create: `sim/tb_darkriscv_dot4.v`
- Modify: `rtl/core/darkriscv.v`
- Modify: `rtl/core/darkriscv_config.vh`
- Modify: `rtl/soc/darkriscv_adapter.v`

**Interfaces:** 仅 `custom-0/funct3=0/funct7=0` 合法。

- [x] 先观察协处理器端口缺失的失败测试。
- [x] 接入 CPR request/result/ack 与 `CPR_PC`。
- [x] 覆盖结果、相邻 DOT4、x0、非法编码和 stall 中 timer IRQ。
- [x] 运行 machine trap、`rv32i_safe` 和 `rv32mi_dark`。

### Task 3: firmware ABI 与性能对照

**Files:**
- Create: `firmware/accel/dot4.h`
- Create: `firmware/accel/dot4.S`
- Create: `firmware/apps/baremetal/benchmarks/dot4_bench.c`
- Create: `scripts/test_dot4_benchmark.sh`
- Modify: `scripts/build_firmware.sh`
- Modify: `Makefile`

**Interfaces:** `int dot4_s8(unsigned int a, unsigned int b)`;显式
`FIRMWARE_ACCEL=dot4`。

- [x] 先观察 `dot4_s8` undefined reference。
- [x] 增加 `.insn r CUSTOM_0, 0, 0, a0, a0, a1` ABI。
- [x] 比较相同输入的 checksum、cycles 和 instret。
- [x] 自动要求 custom cycles/instret 均低于 scalar。

### Task 4: 文档、回归与人工 Gate

**Files:**
- Create: `docs/DOT4_CUSTOM_ISA.md`
- Modify: `README.md`
- Modify: `docs/PROJECT_SPEC.md`
- Modify: `docs/BENCHMARKS.md`
- Modify: `scripts/export_ise_project.sh`

- [x] 增加 `dot4` suite 和 `make dot4-bench`。
- [x] 增加 `minisoc_dot4_dark` ISE 导出目标。
- [x] 从共同基线 `35968e6` 生成无 DOT4 的 `minisoc_dark` PPA 对照包,并验证两份导出包可脱离源码树独立 elaboration。
- [x] fresh 运行 `dot4`、smoke、RV32I、RV32MI completion gate。
- [ ] 用户执行 ISE Map/PAR/Timing 与真实上板验证。
46 changes: 46 additions & 0 deletions docs/superpowers/specs/2026-07-13-darkriscv-custom-dot4-design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# DarkRISCV custom-0 DOT4 设计

## 目标与边界

TecPlusRV 在 DarkRISCV profile 中实现一条非标准 `dot4.s8 rd, rs1, rs2`:两个
32-bit 源寄存器各打包四个 signed INT8,硬件完成四组乘法并求和,将 signed
32-bit 结果写回 `rd`。

第一版不修改 PicoRV32,不实现完整 SIMD/Vector ISA,不使用旧 `rd` 作为累加输入。
MMIO frontend 作为后续接口开销实验,不进入本轮实现。

## 编码与异常

```text
opcode = 0001011 (custom-0)
funct3 = 000
funct7 = 0000000
```

lane 0 固定为 `[7:0]`,lane 3 固定为 `[31:24]`。除上述编码外的 custom-0
必须触发 illegal-instruction trap;`rd=x0` 不得改变 x0。

## 硬件结构

独立 `rtl/accel/dot4_int8.v` 负责 signed 乘加。DarkRISCV 通过现有 `CPR_*`
协处理器接口连接,新增 `CPR_PC` 作为 transaction tag。结果寄存后只对相同 PC
拉高 ACK;相邻 DOT4 的 PC 改变会立即撤销旧 ACK,避免重复接收或复用旧结果。

协处理器等待沿用 core 的 `HLT`。interrupt 在 DOT4 完成后的完整指令边界进入,
性能计数器对每条合法 DOT4 只计一次提交。

## 软件与验证

`firmware/accel/dot4.S` 提供 `dot4_s8(a, b)` ABI,只有显式
`FIRMWARE_ACCEL=dot4` 才链接;其余 firmware 保持 RV32I。

验证分为:

1. signed lane、边界值、reset 和相邻 transaction 的模块级 testbench;
2. 写回、x0、非法编码、stall/retire 和 timer IRQ 的 core-level 汇编测试;
3. scalar/custom checksum、cycles、instret 的 MiniSoC benchmark;
4. 官方 RV32I/RV32MI 与现有 smoke 回归;
5. ISE Map/PAR/Timing 和真实上板人工 Gate。

Icarus 只证明 RTL 功能和相对周期结果。DSP48A1 推断、资源增量、50 MHz slack 与
板级 UART 行为必须以 ISE 和真实硬件证据为准。
10 changes: 10 additions & 0 deletions firmware/accel/dot4.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# int dot4_s8(unsigned int packed_a, unsigned int packed_b)
# a0/a1 直接作为 rs1/rs2,结果按 ABI 返回到 a0。
.section .text
.align 2
.globl dot4_s8
.type dot4_s8, @function
dot4_s8:
.insn r CUSTOM_0, 0, 0, a0, a0, a1
ret
.size dot4_s8, .-dot4_s8
7 changes: 7 additions & 0 deletions firmware/accel/dot4.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// DarkRISCV custom-0 DOT4 软件接口。
#ifndef DOT4_H
#define DOT4_H

int dot4_s8(unsigned int packed_a, unsigned int packed_b);

#endif
Loading
Loading