10 KiB
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 fromstatic/. - Computation Engine (
dea/):filter_design.py: Usesscipy.signalto 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 直接 servestatic/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
- Design: User selects a filter type or enters coefficients manually.
- Quantize: User adjusts Q-format bits to see how quantization affects the frequency response.
- Verify: User uploads a CSV to see how the filter behaves with real-world signals.
- 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 後依然能看到最高精度的時域微小细節(如量化雜訊與過渡漣波)。
- 當使用者在前端圖表進行 Zoom / Pan 縮放時,系統會捕捉可視的時序區間,轉換成數列 Index,向後端發送包含
- 時序比例鎖定 (Stable Time Scaling):
- 將時間軸單位與 multiplier 在波形首次全載入時進行計算與鎖定(如
ms、μs或s),避免了 Plotlyuirevision狀態因 Zoom In 觸發單位動態改變所引發的座標軸錯位(Clashing)。
- 將時間軸單位與 multiplier 在波形首次全載入時進行計算與鎖定(如
- 重繪遞迴鎖定旗標 (Redraw Loop Lock):
- 實作了
isRedrawingTimePlot狀態鎖。在前端執行Plotly.react()佈局重繪時,自動遮蔽並忽略所引發的同步plotly_relayout佈局回呼,完全消除了繪圖重繪與 API 請求之間的 recursive 無窮迴圈,保證在 50 萬筆大資料下縮放依然流暢。
- 實作了
4. 限縮數據全新 CSV 匯出與多長度支援 (Restructured Export & NaN-Dropping)
- 精簡 4 欄 CSV 結構:
- 匯出下載功能不再沿用並污染原本包含無數無關欄位的上傳 CSV 檔案,而是主動為使用者建構並匯出一個全新、精簡的 4 欄式專屬 CSV 檔案:
Time (s):由前端傳送取樣率fs,後端根據實際數據點 Index 精確計算之秒數時間軸。[原輸入欄位]:去除無效欄位與尾部 NaN 的原始時域輸入。[原輸入欄位]_filtered_ideal:理想浮點數二階級聯濾波器輸出。[原輸入欄位]_filtered_fixed:定點數硬體級 Round/Floor 濾波器模擬輸出。
- 匯出下載功能不再沿用並污染原本包含無數無關欄位的上傳 CSV 檔案,而是主動為使用者建構並匯出一個全新、精簡的 4 欄式專屬 CSV 檔案:
- 不同訊號長度支援 (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)」,確保上傳檔案的安全驗證防線不被破壞。
- 後端 CSV 處理器支援每一訊號欄位擁有獨立的實體有效長度。當資料讀入時,後端會自動套用
🛠 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_bbits 小數精度。
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。請用純整數實作:這個技巧已實作於本工具前端的「Round (+0.5 補償)」選項中,開啟後可大幅提升信噪比與波形穩定性。// 完美的 1-clock 整數四捨五入寫法 (Round to nearest): // 編譯器會將 (1 << (shift_bits - 1)) 編譯為常數,只會多消耗一個 ADD 指令。 y_out = (acc + (1 << (shift_bits - 1))) >> shift_bits;
⚙️ 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 以允許自簽憑證:
// ✅ 正確 (HTTPS 模式下)
proxy: {
'/api': {
target: 'https://127.0.0.1:8000',
changeOrigin: true,
secure: false
}
}
2. 生產部署流程(純使用者使用)
如果您是純使用者,或者需要進行系統正式展示,完全不需要啟動 Vite Dev Server (5173)! 您只需要在修改前端後進行一次編譯,然後使用 FastAPI 單獨運行 8000 連接埠即可:
# 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 後台服務啟動(開機自動拉起):
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 | 是 | 否,完全不需啟用! |