返回技能列表

simulate-cpu-architecture

pjt222
更新于 5 days ago
12 次查看
17
2
17
在 GitHub 上查看
designdata

关于

This skill enables developers to design and simulate a minimal CPU from scratch, including defining an ISA, building the datapath, and implementing the fetch-decode-execute cycle. It's a capstone exercise for composing combinational and sequential logic blocks into a complete processor. Use it to deeply understand CPU architecture by tracing a program's execution clock cycle by clock cycle.

快速安装

Claude Code

推荐
主要方式
npx skills add pjt222/agent-almanac -a claude-code
插件命令备选方式
/plugin add https://github.com/pjt222/agent-almanac
Git 克隆备选方式
git clone https://github.com/pjt222/agent-almanac.git ~/.claude/skills/simulate-cpu-architecture

在 Claude Code 中复制并粘贴此命令以安装该技能

技能文档

模擬 CPU 架構

從零設計一最小但完整之 CPU:定義指令集架構、組合 ALU 與暫存器檔為資料路徑、設計控制單元為每一指令階段產生正確訊號、實現取指-解碼-執行循環、模擬一小程式至完成、並逐時鐘週期驗證每一暫存器與記憶體狀態。

適用時機

  • 從第一原理學習或教授計算機架構
  • 為 FPGA 或教學模擬器設計自訂處理器
  • 驗證對指令於閘級與暫存器傳輸層執行之理解
  • 建構 CPU 之軟體模擬(Python、JavaScript 或結構化逐步說明)
  • 將 design-logic-circuit 之組合塊與 build-sequential-circuit 之時序塊組合為可運作之系統

輸入

  • 必要:處理器複雜度目標——4 位元、8 位元或 16 位元資料寬度;通用暫存器數(2-16)
  • 必要:最小指令集——至少:load、store、add、subtract、bitwise AND/OR、branch、halt
  • 選擇性:直接定址以外之定址模式(立即、暫存器間接、索引)
  • 選擇性:附加指令(multiply、shift、compare、用於子程式之 jump-and-link)
  • 選擇性:記憶體大小與字寬
  • 選擇性:管線階段(單週期、多週期或管線化)——預設為多週期
  • 選擇性:實現媒介——軟體模擬(Python/JS)、HDL(Verilog/VHDL)或紙上演練

步驟

步驟一:定義指令集架構

指明程式設計師為此 CPU 寫機器碼所需知之一切:

  1. 資料寬度:選擇資料(ALU 運算元大小)與位址之位元寬度。常見選擇:8 位元資料/8 位元位址(256 位元組可定址)、16 位元資料/16 位元位址。
  2. 暫存器檔:定義通用暫存器之數及任何特殊用途暫存器。
    • 通用:R0-R(N-1)。決定 R0 是否硬接至零(簡化指令編碼)。
    • 特殊用途:程式計數器(PC)、指令暫存器(IR)、狀態/旗標暫存器(Zero、Carry、Negative、Overflow)。
  3. 指令格式:設計固定寬度之指令字。將位元分為欄位:
    • Opcode:識別運算。以 K 位元,可支援至 2^K 條指令。
    • 暫存器欄位:源與目的暫存器位址。N 個暫存器時,每欄位需 ceil(log2(N)) 位元。
    • 立即/偏移欄位:用於常數或分支偏移。用剩餘位元。
  4. 指令目錄:定義每條指令之助記符、opcode 編碼、運算元欄位、運算(以 RTL 表示法)及受影響旗標。
  5. 定址模式:定義運算元如何定位。
    • 暫存器:運算元在暫存器中。
    • 立即:運算元嵌入指令中。
    • 直接:運算元位址在指令中。
    • 暫存器間接:運算元位址在暫存器中。
## ISA Specification
- **Data width**: [N] bits
- **Address width**: [M] bits
- **Registers**: [count] general-purpose + [list of special-purpose]
- **Instruction width**: [W] bits

### Instruction Format
| Field    | Bits      | Width |
|----------|-----------|-------|
| Opcode   | [W-1:X]  | [n]   |
| Rd       | [X-1:Y]  | [n]   |
| Rs       | [Y-1:Z]  | [n]   |
| Imm      | [Z-1:0]  | [n]   |

### Instruction Catalog
| Mnemonic | Opcode | Format    | RTL Operation          | Flags |
|----------|--------|-----------|------------------------|-------|
| LOAD     | 0000   | Rd, [addr]| Rd <- MEM[addr]       | -     |
| STORE    | 0001   | Rs, [addr]| MEM[addr] <- Rs       | -     |
| ADD      | 0010   | Rd, Rs    | Rd <- Rd + Rs         | Z,C,N |
| ...      | ...    | ...       | ...                    | ...   |
| HALT     | 1111   | -         | Stop execution         | -     |

預期: 完整之 ISA 規格,每條指令具獨一 opcode、明確之運算元欄位、無歧義之 RTL 描述及記錄之旗標效應。指令編碼須可無歧義解碼。

失敗時: 若指令字過窄無法編碼所有需要欄位,要麼加寬指令、減少暫存器數、用變長指令(解碼較複雜),要麼將指令拆為次運算。若 opcode 衝突,重新分配編碼。

步驟二:設計資料路徑

建構移動與變換資料之暫存器傳輸層硬體:

  1. ALU:以 design-logic-circuit 技能設計。ALU 取二 N 位元運算元與一運算選擇訊號,產生 N 位元結果及旗標輸出(Zero、Carry、Negative、Overflow)。
    • 運算:ADD、SUB(透過二補數加)、AND、OR、XOR、NOT、SHIFT LEFT、SHIFT RIGHT、PASS-THROUGH(用於搬移與載入)。
    • ALU 選擇寬度須容納所有所需運算。
  2. 暫存器檔:以 build-sequential-circuit 設計。一組暫存器具:
    • 二讀埠(源 A、源 B)——以暫存器位址為輸入之組合讀。
    • 一寫埠(目的)——由 RegWrite 控制訊號啟用之時鐘寫。
    • 若 R0 硬接至零,覆蓋對 R0 之寫。
  3. 程式計數器(PC):N 位元暫存器具:
    • 遞增邏輯(為下一順序指令之 PC + instruction_width/8)。
    • 分支/跳轉目標之載入輸入。
    • 由 PCsrc 訊號控制、於遞增與分支目標間選擇之多工器。
  4. 記憶體介面:分離或統一之指令與資料記憶體。
    • 哈佛架構:分離之指令記憶體(執行期間僅讀)與資料記憶體(讀寫)。較簡,允許同時取指與資料存取。
    • 馮諾依曼架構:指令與資料共用單一記憶體。需於不同週期排序取指與資料存取。
  5. 互連:連接組件之多工器與匯流排:
    • ALU 輸入 A 多工器:暫存器讀埠 A 或 PC(用於 PC 相對定址)。
    • ALU 輸入 B 多工器:暫存器讀埠 B 或符號擴展之立即值。
    • 暫存器寫資料多工器:ALU 結果或記憶體讀資料(用於 load)。
    • 記憶體位址多工器:PC(用於指令取指)或 ALU 結果(用於 load/store)。
## Datapath Components
| Component       | Width  | Ports / Signals                    |
|----------------|--------|------------------------------------|
| ALU            | [N]-bit| OpA, OpB, ALUop -> Result, Flags  |
| Register File  | [N]-bit| RdAddrA, RdAddrB, WrAddr, WrData, RegWrite -> RdDataA, RdDataB |
| PC             | [M]-bit| PCnext, PCwrite -> PCout           |
| Instruction Mem| [W]-bit| Addr -> Instruction                |
| Data Memory    | [N]-bit| Addr, WrData, MemRead, MemWrite -> RdData |

## Datapath Multiplexers
| Mux Name     | Inputs               | Select Signal | Output      |
|-------------|----------------------|---------------|-------------|
| ALU_B_mux   | RegDataB, Immediate  | ALUsrc        | ALU OpB     |
| WrData_mux  | ALU Result, MemData  | MemToReg      | Reg WrData  |
| PC_mux      | PC+1, BranchTarget   | PCsrc         | PC next     |

預期: 完整之資料路徑圖(以組件表與多工器表呈現),其中 ISA 中每條指令皆有可行路徑,使其資料能由源經 ALU、暫存器檔與記憶體流至目的。

失敗時: 若某指令無法以當前資料路徑執行(如 LOAD 無自記憶體至暫存器之路徑),加入缺少之多工器或資料路徑。逐條走過每指令之 RTL 運算,並追蹤所需訊號流經資料路徑。

步驟三:設計控制單元

建構為每條指令編排資料路徑之邏輯:

  1. 識別控制訊號:列出資料路徑中之每一多工器選擇、暫存器寫使能、記憶體讀/寫使能與 ALU 運算選擇訊號。
  2. 單週期控制(最簡):純組合控制單元,於一時鐘週期內由當前指令之 opcode 欄位導出所有控制訊號。
  3. 多週期控制(學習推薦):以 build-sequential-circuit 設計之有限狀態機,將每指令拆為階段:
    • Fetch:自 PC 位址讀取指令;存入 IR;遞增 PC。
    • Decode:以 IR 欄位讀暫存器檔;符號擴展立即欄位。
    • Execute:執行 ALU 運算或計算記憶體位址。
    • Memory access(僅 load/store):自資料記憶體讀或寫之。
    • Write-back:將結果寫至目的暫存器。
  4. 控制訊號表:對每條指令與每一階段,指明每控制訊號之值。
  5. 硬接式 vs. 微程式式
    • 硬接式:控制 FSM 由閘與正反器構成。較快,較不靈活。
    • 微程式式:微指令 ROM 存每狀態之控制訊號。每微指令含控制訊號值與下一狀態欄位。較慢,但易修改。
## Control Signals
| Signal     | Width | Function                              |
|-----------|-------|---------------------------------------|
| ALUop     | [k]   | Selects ALU operation                 |
| ALUsrc    | 1     | 0=register, 1=immediate for ALU B    |
| RegWrite  | 1     | Enable register file write            |
| MemRead   | 1     | Enable data memory read               |
| MemWrite  | 1     | Enable data memory write              |
| MemToReg  | 1     | 0=ALU result, 1=memory data to register |
| PCsrc     | 1     | 0=PC+1, 1=branch target              |
| IRwrite   | 1     | Enable instruction register load      |

## Multi-Cycle Control FSM
| State   | Active Signals                          | Next State         |
|---------|----------------------------------------|-------------------|
| FETCH   | MemRead, IRwrite, PC <- PC+1           | DECODE             |
| DECODE  | Read registers, sign-extend immediate   | EXECUTE            |
| EXECUTE | ALUop=[per instruction], ALUsrc=[...]  | MEM_ACCESS or WB   |
| MEM_ACC | MemRead or MemWrite                    | WRITE_BACK         |
| WB      | RegWrite, MemToReg=[...]               | FETCH              |

預期: 控制單元(組合或 FSM)為每條指令之每階段產生正確之控制訊號值,無相衝訊號(如同一記憶體上同時 MemRead 與 MemWrite)。

失敗時: 若有控制訊號衝突,階段未妥善分離。確保 load 與 store 於不同階段存取記憶體,或記憶體介面支援於分離埠之同時讀寫。若 FSM 狀態過多,檢查某些指令是否共享階段而可合併。

步驟四:實現取指-解碼-執行循環

連接資料路徑與控制單元為可運作處理器:

  1. 時鐘分配:將系統時鐘連至所有正反器(PC、IR、暫存器檔、控制 FSM 狀態暫存器)。所有狀態更新於同一時鐘邊緣發生。
  2. 階段排序:將控制 FSM 輸出接至資料路徑控制訊號。FSM 每時鐘週期前進一狀態,驅動資料路徑經 Fetch -> Decode -> Execute -> Memory -> Write-back。
  3. 指令取指:於 FETCH 階段,PC 驅動指令記憶體位址匯流排。所取指令載入 IR。PC 遞增一指令寬度。
  4. 指令解碼:於 DECODE 階段,IR 之 opcode 欄位驅動控制單元以判定指令類型。IR 之暫存器位址驅動暫存器檔讀埠。
  5. 執行及之後:餘下階段視指令類型而定:
    • ALU 指令:Execute(ALU 計算)、Write-back(結果至暫存器)。
    • Load:Execute(ALU 計算位址)、Memory(讀資料記憶體)、Write-back(資料至暫存器)。
    • Store:Execute(ALU 計算位址)、Memory(寫資料記憶體)。
    • Branch:Execute(ALU 比較或檢查旗標)、條件性更新 PC。
    • Halt:FSM 進終止狀態並停前進。
  6. 中斷與例外處理(選擇性):加入機制以保存 PC 並跳至處理器位址。需附加控制狀態與原因暫存器。
## Cycle Execution Summary
| Instruction Type | Phases                          | Cycles |
|-----------------|--------------------------------|--------|
| ALU (reg-reg)   | Fetch, Decode, Execute, WB     | 4      |
| Load            | Fetch, Decode, Execute, Mem, WB| 5      |
| Store           | Fetch, Decode, Execute, Mem    | 4      |
| Branch (taken)  | Fetch, Decode, Execute         | 3      |
| Branch (not taken)| Fetch, Decode, Execute       | 3      |
| Halt            | Fetch, Decode                  | 2      |

預期: 全連通之處理器,控制 FSM 為每指令類型驅動資料路徑經正確階段序列,所有狀態轉換於時鐘邊緣同步發生。

失敗時: 若處理器卡死(永不達 HALT)或產生錯誤結果,最可能因為某特定階段之控制訊號錯誤。用步驟五之逐週期追蹤隔離失敗週期。若 PC 不正確遞增,檢查 FETCH 階段佈線。若寫至錯誤暫存器,檢查 IR 之暫存器位址欄位提取。

步驟五:模擬一小程式並驗證

執行具體程式並逐時鐘週期驗證預期狀態:

  1. 寫測試程式:選一程式小至可完整追蹤(5-15 條指令)但複雜至能演練多種指令類型。費氏數列計算為理想:用 load-immediate、add、branch 與 halt。
  2. 初始化狀態:所有暫存器置零。將程式自位址 0 開始載入指令記憶體。設 PC = 0。將控制 FSM 置 FETCH 狀態。
  3. 逐週期追蹤:對每時鐘週期記錄:
    • 控制 FSM 狀態與階段名
    • PC 值與正取指/執行之指令
    • ALU 輸入、運算與結果
    • 暫存器檔讀寫
    • 記憶體讀寫
    • 旗標暫存器值
    • 所有控制訊號值
  4. 與手算驗證:獨立計算每指令完成後(非每週期——每指令需多週期)之預期暫存器與記憶體狀態。將模擬追蹤與此預期快照比對。
  5. 邊界情況:驗證以下行為:
    • 分支不採(PC 正常遞增)
    • 分支採(PC 載入分支目標)
    • load 後立即使用所載暫存器(檢查寫回是否於下次解碼讀之前完成)
    • 寫至 R0(若硬接零,寫應無效)
    • HALT 指令(處理器乾淨停止)
## Test Program: Fibonacci (first 8 terms)
| Addr | Instruction    | Mnemonic         | Comment              |
|------|---------------|------------------|----------------------|
| 0x00 | [encoding]    | LOAD R1, #1      | R1 = 1 (F1)         |
| 0x01 | [encoding]    | LOAD R2, #1      | R2 = 1 (F2)         |
| 0x02 | [encoding]    | LOAD R3, #6      | R3 = 6 (loop count) |
| 0x03 | [encoding]    | ADD R4, R1, R2   | R4 = R1 + R2        |
| 0x04 | [encoding]    | MOV R1, R2       | R1 = R2              |
| 0x05 | [encoding]    | MOV R2, R4       | R2 = R4              |
| 0x06 | [encoding]    | SUB R3, R3, #1   | R3 = R3 - 1         |
| 0x07 | [encoding]    | BNZ 0x03         | Branch if R3 != 0   |
| 0x08 | [encoding]    | HALT             | Stop                 |

## Cycle-by-Cycle Trace (excerpt)
| Cycle | Phase   | PC  | IR       | ALU Op   | Result | RegWrite | Flags |
|-------|---------|-----|----------|----------|--------|----------|-------|
| 1     | FETCH   | 0x00| LOAD R1,1| -        | -      | No       | -     |
| 2     | DECODE  | 0x01| LOAD R1,1| -        | -      | No       | -     |
| 3     | EXECUTE | 0x01| LOAD R1,1| PASS #1  | 1      | No       | -     |
| 4     | WB      | 0x01| LOAD R1,1| -        | -      | R1 <- 1  | -     |
| ...   | ...     | ... | ...      | ...      | ...    | ...      | ...   |

## Expected Final State
| Register | Value | Description         |
|----------|-------|---------------------|
| R1       | [val] | Second-to-last Fib  |
| R2       | [val] | Last computed Fib   |
| R3       | 0     | Loop counter done   |
| R4       | [val] | Same as R2          |
| PC       | 0x09  | One past HALT       |

預期: 逐週期追蹤與預期最終狀態相符。每指令產生正確之暫存器與記憶體更新。程式於 HALT 終止,暫存器中含正確費氏值。

失敗時: 比對預期與實際狀態之首次分歧。常見因:(1) 某指令類型之 ALU 運算選擇錯誤——檢查控制訊號表。(2) 分支偏移計算差一——驗證分支是 PC 相對於當前還是下一指令位址。(3) 寫回寫至錯誤暫存器——檢查暫存器位址欄位提取。(4) 旗標未正確更新——對致差錯之具體運算元追蹤 ALU 旗標邏輯。

驗證

  • ISA 至少含 load、store、add、subtract、AND、OR、branch 與 halt 指令
  • 每指令具獨一 opcode 與無歧義編碼
  • 資料路徑為每指令之 RTL 運算提供有效訊號路徑
  • ALU 支援所有所需運算且旗標生成正確
  • 暫存器檔有足夠讀寫埠以滿足指令格式
  • 控制單元為每指令之每階段產生正確訊號
  • 無控制訊號衝突(如同一記憶體埠之同時讀寫)
  • 取指-解碼-執行循環完全連通且時鐘化
  • 測試程式執行至完成且最終狀態正確
  • 逐週期追蹤已與手算驗證
  • 分支採與不採案例皆已驗證
  • HALT 指令乾淨停止執行

常見陷阱

  • 分支偏移差一:分支可能相對當前 PC、PC+1 或分支後之指令。於 ISA 中定義慣例並一致實現。分支目標之差一錯誤為 CPU 設計最單一常見之臭蟲。
  • 多週期中之寫回/解碼相依:若指令 I 於寫回階段寫某暫存器,同時指令 I+1 於解碼階段讀該暫存器,讀可能取舊值。多週期 CPU(一次一指令)不為問題。管線化 CPU 則需轉送或暫停。
  • 取指時忘記遞增 PC:若 FETCH 階段未遞增 PC,CPU 將永遠執行同一指令。為極常見之佈線錯誤。
  • ALU 旗標鎖存:旗標應僅於 ALU 指令時更新,非於 load、store 或 branch。若旗標無條件更新,比較與分支間之 load 將破壞比較結果。
  • 無號 vs. 有號混淆:於 ISA 定義時決定算術為有號(二補數)或無號,並依此實現 ALU 與旗標邏輯。Carry 旗標於有號 vs. 無號運算中語義不同。
  • 記憶體對齊:若資料寬度與指令寬度不同,或指令多位元組,定義對齊規則。位元組可定址記憶體中之 16 位元指令佔兩位址;PC 須遞增 2 而非 1。
  • 首次設計過於複雜:自最簡可能 CPU 起(8 位元、4 暫存器、8 指令、單週期或多週期、無管線)。複雜可後加;可運作之簡單設計教益勝於損壞之複雜者。

相關技能

  • design-logic-circuit — 設計 ALU、多工器、解碼器與其他組合塊
  • build-sequential-circuit — 設計暫存器檔、程式計數器、控制 FSM 與其他時序塊
  • evaluate-boolean-expression — 簡化硬接控制單元之控制邏輯方程
  • derive-theoretical-result — 形式化效能分析(CPI、吞吐、Amdahl 定律)

GitHub 仓库

pjt222/agent-almanac
路径: i18n/wenyan-lite/skills/simulate-cpu-architecture
0
agentsagentskillsai-assisted-developmentclaude-codeskillsteams

相关推荐技能

content-collections

Content Collections 是一个 TypeScript 优先的构建工具,可将本地 Markdown/MDX 文件转换为类型安全的数据集合。它专为构建博客、文档站和内容密集型 Vite+React 应用而设计,提供基于 Zod 的自动模式验证。该工具涵盖从 Vite 插件配置、MDX 编译到生产环境部署的完整工作流。

查看技能

polymarket

这个Claude Skill为开发者提供完整的Polymarket预测市场开发支持,涵盖API调用、交易执行和市场数据分析。关键特性包括实时WebSocket数据流,可监控实时交易、订单和市场动态。开发者可用它构建预测市场应用、实施交易策略并集成实时市场预测功能。

查看技能

creating-opencode-plugins

该Skill帮助开发者创建OpenCode插件,用于接入命令、文件、LSP等25+种事件。它提供了插件结构、事件API规范和JavaScript/TypeScript实现模式,适合需要拦截操作、扩展功能或自定义事件处理的场景。开发者可通过它快速构建响应式模块来增强OpenCode AI助手的能力。

查看技能

sglang

SGLang是一个专为LLM设计的高性能推理框架,特别适用于需要结构化输出的场景。它通过RadixAttention前缀缓存技术,在处理JSON、正则表达式、工具调用等具有重复前缀的复杂工作流时,能实现极速生成。如果你正在构建智能体或多轮对话系统,并追求远超vLLM的推理性能,SGLang是理想选择。

查看技能