Files
tcad-bodeplot/ARCHITECTURE.md
T

148 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Difference Equation Analyzer (DEA) - Architecture & Functionality
## Overview
DEA is a specialized tool for designing, visualizing, and validating discrete-time filters. It bridges the gap between theoretical filter design (floating-point) and hardware implementation (fixed-point/MCU).
## 🏗 System Architecture
### 1. Backend (Python 3.12 + FastAPI)
The backend is responsible for heavy mathematical computations and data processing.
- **API Entry (`dea_api.py`)**: Routes requests to appropriate modules and serves the Vue.js frontend from `static/`.
- **Computation Engine (`dea/`)**:
- `filter_design.py`: Uses `scipy.signal` to calculate coefficients for various filter topologies.
- `bode.py`: Computes magnitude and phase response. Supports comparing "Ideal" (float) vs "Fixed" (quantized) responses.
- `csv_processing.py`: Processes time-domain CSV data. It applies the current filter to the signal and downsamples the result for efficient visualization.
- `validation.py`: Protects against unstable filter designs and invalid inputs.
### 2. Frontend (Vue 3 + Vite + Tailwind)
A reactive "Single Page Application" (SPA) approach.
> ⚠️ **開發 vs 部署 (Development vs Production)**
> - **開發模式 (Development)**: 透過 `npm run dev` 啟動 Vite dev server (預設 `http://localhost:5173`)。前端原始碼修改後會自動熱更新 (HMR),**不需要** 手動 build。API 請求透過 `vite.config.js` 的 proxy 設定轉發至後端。
> - **生產模式 (Production)**: 透過 `http://localhost:8000/ui/` 存取。FastAPI 直接 serve `static/build/` 裡的 production bundle。**修改 `src/` 原始碼後,必須執行 `npm run build` 才會生效**。忘記 build 會導致前端程式碼與後端不同步,所有新功能看起來都「沒有作用」。
- **Reactive Logic (`src/app-options.js`)**:
- Manages the state of all coefficients.
- Implements "Fine-tuning" sliders that allow real-time adjustment of poles/zeros.
- Handles Fixed-Point conversion logic (Q-format shifting).
- **UI Components (`src/App.vue`)**:
- **Control Sidebar**: Interactive inputs for all filter parameters.
- **Visualization**: Dual-plot system using Plotly.js for Bode plots and Time-domain waveforms.
- **Hardware Bridge**: Uses the **Web Serial API** to send commands directly to connected MCUs (requires HTTPS).
## 🚀 Execution Flow
1. **Design**: User selects a filter type or enters coefficients manually.
2. **Quantize**: User adjusts Q-format bits to see how quantization affects the frequency response.
3. **Verify**: User uploads a CSV to see how the filter behaves with real-world signals.
4. **Deploy**: User clicks "Write to MCU" to send the coefficients to their hardware.
## 🛠 Tech Stack
- **Backend**: FastAPI, NumPy, SciPy, Pandas, Uvicorn.
- **Frontend**: Vue 3, Vite, Tailwind CSS, Plotly.js.
- **Security**: Restricted to LAN/Loopback; implemented security headers and HTTPS support.
---
## 💎 V2 Feature: Parallel Fixed-Point Simulation
本分支 (`dev-v2-integretimedomain`) 的核心任務是在時域分析中實作「雙路徑對照系統」:
### 1. 雙路徑模擬邏輯 (Dual-Path Logic)
- **理想路徑 (Float Path)**: 使用 64-bit 浮點數進行運算,作為效能基準。
- **硬體模擬路徑 (Integer Path)**:
- **輸入量化**: 將原始訊號依 $Q_{in}$ 轉為整數。
- **整數運算**: 使用整數係數 ($Q_{coeff}$) 進行差分方程式計算。
- **位移校準**: 運算過程中考慮累加器位元數,並依 $Q_{out}$ 進行最終縮放。
- **效果**: 模擬真實 DSP 的捨入誤差 (Rounding Error) 與量化雜訊。
### 2. 資料流更新
- **API `/api/filter`**: 接收檔案 ID 與係數參數,返回兩組數列(Float / Fixed)。
- **UI 圖表**: 同時繪製兩條曲線,讓開發者直觀判斷量化是否導致不穩定 (Instability) 或顯著失真。
### 3. 高效能資料處理與區域高畫質重取樣架構 (Adaptive LOD & Resampling)
- **區域高畫質重取樣 (LOD Zoom Resampling)**:
- 當使用者在前端圖表進行 Zoom / Pan 縮放時,系統會捕捉可視的時序區間,轉換成數列 Index,向後端發送包含 `start_idx``end_idx` 的 Form 參數。
- 後端保持**全時域 IIR 濾波器狀態暫存與記憶運算**(保證濾波響應的物理與數學狀態 100% 正確),但僅針對該可視區間進行切片 (Slice) 並降採樣至 5,000 點傳回,在大幅減少頻寬的同時,讓使用者在 Zoom In 後依然能看到最高精度的時域微小细節(如量化雜訊與過渡漣波)。
- **時序比例鎖定 (Stable Time Scaling)**:
- 將時間軸單位與 multiplier 在波形**首次全載入時進行計算與鎖定**(如 `ms``μs``s`),避免了 Plotly `uirevision` 狀態因 Zoom In 觸發單位動態改變所引發的座標軸錯位(Clashing)。
- **重繪遞迴鎖定旗標 (Redraw Loop Lock)**:
- 實作了 `isRedrawingTimePlot` 狀態鎖。在前端執行 `Plotly.react()` 佈局重繪時,自動遮蔽並忽略所引發的同步 `plotly_relayout` 佈局回呼,完全消除了繪圖重繪與 API 請求之間的 recursive 無窮迴圈,保證在 50 萬筆大資料下縮放依然流暢。
### 4. 限縮數據全新 CSV 匯出與多長度支援 (Restructured Export & NaN-Dropping)
- **精簡 4 欄 CSV 結構**:
- 匯出下載功能不再沿用並污染原本包含無數無關欄位的上傳 CSV 檔案,而是主動為使用者建構並匯出一個**全新、精簡的 4 欄式專屬 CSV 檔案**:
1. `Time (s)`:由前端傳送取樣率 `fs`,後端根據實際數據點 Index 精確計算之秒數時間軸。
2. `[原輸入欄位]`:去除無效欄位與尾部 NaN 的原始時域輸入。
3. `[原輸入欄位]_filtered_ideal`:理想浮點數二階級聯濾波器輸出。
4. `[原輸入欄位]_filtered_fixed`:定點數硬體級 Round/Floor 濾波器模擬輸出。
- **不同訊號長度支援 (NaN-Dropping)**:
- 後端 CSV 處理器支援每一訊號欄位擁有**獨立的實體有效長度**。當資料讀入時,後端會自動套用 `.dropna()` 拋棄尾部空白 `NaN`,並將系統點數 `total_points` 動態截斷為實際有效長度(例如 Step 預設訊號自動截斷為 `100 ms` 的 10,001 行,McDonald's Wave 自動截斷為 `200 ms` 的 20,001 行),極大提升了模擬運算速度與匯出精準度。
- 同時實施了索引遮罩比對 `(numeric_nans & ~original_nans)`,能精準區分「因長度不足產生的尾部空白」與「因 CSV 資料損毀產生的非數值字串 (如 bad)」,確保上傳檔案的安全驗證防線不被破壞。
---
## 🛠 Firmware Implementation Guidelines (韌體實作指引)
在將此工具設計出來的濾波器係數移植到 C 語言或 MCU (如 RISC-V) 時,請務必遵守以下實作準則,以確保硬體行為與本系統的模擬結果 100% 一致:
### 1. 高精度狀態變數架構 (Extended Precision State Variables)
為了極小化截斷誤差 (Truncation Error),硬體實作的迴圈請**不要**對前饋 (Feed-forward) 進行位移。
- **作法**:讓歷史陣列 `y_history[]` 保存前饋乘加後的高精度格式 ($Q_{in+b}$)。僅在計算回授 (Feedback) 的乘積後,才對回授項進行右移對齊,並在最終輸出給硬體腳位時做最後的右移。這等於讓 IIR 濾波器內部默默保留了額外的 $Q_b$ bits 小數精度。
### 2. 消除直流偏移 (DC Bias) 的 1-Clock Rounding 演算法秘技
傳統的右移 (`>>`) 會造成無條件捨去向下取整 (Floor),這會引入永遠為負的平均誤差 ($-0.5$ LSB),導致濾波器產生直流偏移。必須改用四捨五入 (Rounding)。
- **硬體現狀**:標準的 RISC-V 指令集 (RV32I / RV32IMAC) **沒有**硬體的 round off shift 指令 (其 `SRA` 指令是純 Floor)。除非晶片具備 DSP 擴充指令集 ('P' Extension)。
- **C 語言實作秘技**:絕對**不要**為了四捨五入去呼叫 C standard library 的 `round()`,這會啟動浮點數運算,吃掉上百個 Clock。請用純整數實作:
```c
// 完美的 1-clock 整數四捨五入寫法 (Round to nearest):
// 編譯器會將 (1 << (shift_bits - 1)) 編譯為常數,只會多消耗一個 ADD 指令。
y_out = (acc + (1 << (shift_bits - 1))) >> shift_bits;
```
這個技巧已實作於本工具前端的「Round (+0.5 補償)」選項中,開啟後可大幅提升信噪比與波形穩定性。
---
## ⚙️ Deployment & Development Notes (部署與開發環境注意事項)
為了支援 **Web Serial API** 直接與外部 MCU 通訊,本專案在生產與正式使用中**全面採用 HTTPS 加密傳輸**。這對於開發代理(Proxy)與存取路徑有以下影響:
### 1. Vite Proxy 與 SSL 協定對齊
當 Uvicorn 以 **HTTPS** 模式啟動時(綁定 `key.pem` 與 `cert.pem`),Vite Dev Server 的 `/api` 代理目標**必須對齊為 `https://`**,並加上 `secure: false` 以允許自簽憑證:
```js
// ✅ 正確 (HTTPS 模式下)
proxy: {
'/api': {
target: 'https://127.0.0.1:8000',
changeOrigin: true,
secure: false
}
}
```
### 2. 生產部署流程(純使用者使用)
如果您是**純使用者**,或者需要進行系統正式展示,**完全不需要啟動 Vite Dev Server (5173)**
您只需要在修改前端後進行一次編譯,然後使用 FastAPI 單獨運行 8000 連接埠即可:
```bash
# 1. 前端編譯 (只需在修改 src/ 代碼後執行一次,若無修改則免)
npm run build # 將 Vue 代碼打包至 static/build/
# 2. 啟動後端 HTTPS 服務 (同時提供 API 與網頁 UI)
.venv/bin/uvicorn dea_api:app --host 0.0.0.0 --port 8000 --ssl-keyfile certs/key.pem --ssl-certfile certs/cert.pem
```
或直接利用 systemd 後台服務啟動(開機自動拉起):
```bash
sudo systemctl restart dea.service
```
### 3. 開發模式 vs 生產模式對照表
| 項目 | 開發模式 (Vite Dev Server) | 生產模式 (FastAPI Static Serve) |
|------|----------------|---------------------|
| **運行連接埠** | `http://localhost:5173` | `https://localhost:8000/ui/` |
| **後端通訊** | 透過 Vite Proxy 轉發至 8000 (HTTPS) | 同一 Port 直接連線,極致穩定且高效 |
| **修改後生效** | 自動熱更新 (HMR),不需手動 build | 必須執行 `npm run build`,並在瀏覽器進行硬重新整理 |
| **主要用途** | 適合前端網頁排版、UI 除錯開發 | **正式使用、Demo 展示、MCU Web Serial 通訊** |
| **是否需 5173**| **是** | **否,完全不需啟用!** |