Altifigence Academy

19 / 20 · 實作

總整實作:分塊 N×N 驗證模型

結合任意 N、K、填補與暫停,並與獨立參考比較。

組合完整模型

總整實作在 N×N 網格上接受 M×K 的 A 與 K×P 的 B。每個空間分塊從空狀態開始,填補運算元為有效零,寫入依座標遮罩。一次只有一項工作占用分塊,全域暫停保持邏輯時間。輸出量化仍是寬位元總和之後的獨立測試。

儲存為 capstone-lab.mjs 並執行 node capstone-lab.mjs。不需套件。輸入是 JavaScript Number 精確範圍內的小整數測試資料;更大範圍需要 BigInt 與明確位元寬度檢查。這驗證 Node 算術與排程模型,獨立於 RTL 或 DDS 執行。

javascript
import assert from 'node:assert/strict';
function golden(A,B){return A.map(r=>B[0].map((_,j)=>
 r.reduce((s,a,k)=>s+a*B[k][j],0)));}
function solve(A,B,N,pauses=new Set()){
 const M=A.length,K=A[0].length,P=B[0].length;
 assert.ok(N>=1&&Number.isInteger(N)&&K>=1);assert.equal(B.length,K);
 assert.ok(A.every(r=>r.length===K)&&B.every(r=>r.length===P));
 const C=Array.from({length:M},()=>Array(P).fill(null));
 let advances=0,physical=0;
 for(let r0=0;r0<M;r0+=N)for(let c0=0;c0<P;c0+=N){
  const job=r0*P+c0;
  let g=Array.from({length:N},()=>Array.from({length:N},()=>
   ({a:null,b:null,acc:0,count:0})));
  const token=(value,k)=>({value,k,job});let t=0,p=0;
  while(t<K+2*N-2){
   if(pauses.has(p)){p++;continue;}
   const next=g.map(r=>r.map(pe=>({...pe})));
   for(let i=0;i<N;i++)for(let j=0;j<N;j++){
    const ka=t-i,kb=t-j;
    const a=j?g[i][j-1].a:(ka>=0&&ka<K?
     token(r0+i<M?A[r0+i][ka]:0,ka):null);
    const b=i?g[i-1][j].b:(kb>=0&&kb<K?
     token(c0+j<P?B[kb][c0+j]:0,kb):null);
    const pe=next[i][j];pe.a=a;pe.b=b;
    if(a&&b){assert.equal(a.job,b.job);assert.equal(a.k,b.k);
     assert.equal(a.k,pe.count);pe.acc+=a.value*b.value;pe.count++;}}
   g=next;t++;p++;
  }
  for(let i=0;i<N;i++)for(let j=0;j<N;j++){
   assert.equal(g[i][j].count,K);
   if(r0+i<M&&c0+j<P){assert.equal(C[r0+i][c0+j],null);
    C[r0+i][c0+j]=g[i][j].acc;}}
  advances+=t;physical+=p;
 }
 return {C,advances,physical};
}
const A=[[1,2,3],[4,5,6],[7,8,9]],B=[[1,0,2],[0,1,0],[2,0,1]];
for(const N of [1,2,3])assert.deepEqual(
 solve(A,B,N,new Set([1,2])).C,golden(A,B));
const run=solve(A,B,2,new Set([1,2]));
assert.deepEqual(run.C,[[7,2,5],[16,5,14],[25,8,23]]);
assert.equal(run.advances,20);assert.equal(run.physical,28);
assert.deepEqual(solve([[2,-1],[0,3]],[[4,5],[-2,1]],2).C,
 [[10,9],[-6,3]]);
assert.deepEqual(solve([[-128]],[[-128]],1).C,[[16384]]);
console.log('Capstone lab passed');

Golden 函式只知道矩陣算術。求解器獨立移動帶標籤權杖、檢查有序項目,並遮罩寫入。N=2 時,四個分塊需要二十個 advance 邊緣。每個分塊在實體邊緣一與二暫停,增加八次暫停,總共二十八個實體邊緣。不含初始化、記憶體載入與序列化輸出傳輸。

提交紀錄、一個分塊的已消費 k 追蹤、有號位元寬度分析,以及 valid/ready 結果包裝層設計。轉成 RTL 時保留邊緣契約。擴展前先從 N=1,K=1 與 2×2 開始。量化、保留部分和或雙緩衝應逐一加入,並新增明確檢查。

三種網格尺寸測試不同映射:N=1 重複無錯時內積,N=2 測試四個含填補分塊,N=3 使用一個完整分塊。全部必須產生相同數學矩陣。將 C 初始化為 null 可區分有效零與尚未交付輸出,並偵測重複寫入。此處由分塊推導的 job 編號唯一;實際 RTL 必須定義標籤寬度與重用策略。延伸練習可嘗試 M=2,K=3,P=1,先手算預期值。內部網格仍為正方形,輸出矩陣則為長方形。檢查各分塊皆消費完整 K,並抑制超範圍寫入。

自己試試看

3×3 範例使用 N=3,並在實體邊緣一與二暫停,求 advance 與實體邊緣數。若量測包含前面一個 clear 邊緣呢?

查看解說

共有七個 advance 邊緣,以及包含兩次暫停的九個運算區間實體邊緣。包含前面一個 clear 邊緣時為十個;仍不含載入與輸出傳輸。

Lesson files

capstone-lab.mjs ↓

此選擇適用於本瀏覽器,隨時可從頁尾變更。