19 / 20 · Практика
Итоговый проект: модель верификации N×N с блоками
Совместите произвольные N и K с дополнением и паузами и сравните с независимым эталоном.
Уроки доступны бесплатно. Запишитесь, чтобы сохранять прогресс.
Соберите полную модель
Итоговый проект принимает A размера M×K и B размера K×P на сетке N×N. Каждый пространственный блок начинает пустым, дополненные операнды — достоверные нули, а записи маскируются по координатам. Только одно задание занимает блок, и глобальные паузы удерживают логическое время. Выходное квантование остаётся отдельным тестом после широкой суммы.
Сохраните это как capstone-lab.mjs и выполните node capstone-lab.mjs. Пакеты не нужны. Входы — малые целочисленные наборы внутри точного диапазона JavaScript Number; большие диапазоны требуют BigInt и явных проверок разрядности. Это проверяет арифметическую модель и расписание Node независимо от выполнения RTL или DDS.
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');Золотая функция знает только матричную арифметику. Решатель независимо сдвигает токены с метками, проверяет упорядоченные члены и маскирует записи. При 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 даёт десять; загрузка и передача выхода остаются исключёнными.