Altifigence Academy

10 / 20 · Práctica

Práctica: matriz 2×2 con entradas desfasadas

Modela retardos de reenvío de un flanco y comprueba todos los acumuladores intermedios.

Haz que coincidan valores k iguales

Inyecta A(i,k) en el borde izquierdo en el flanco lógico k+i y B(k,j) en el superior en k+j. El reenvío registrado añade j flancos horizontalmente e i verticalmente. Por tanto, ambos operandos llegan a PE(i,j) en k+i+j. Esta inyección escalonada es el desfase de entradas.

Para A=[[1,2],[3,4]], B=[[5,6],[7,8]], el borrado termina antes de E0. Las planificaciones del borde son:

FlancoFila izquierda 0Fila izquierda 1Columna superior 0Columna superior 1
E01(k0)no válido5(k0)no válido
E12(k1)3(k0)7(k1)6(k0)
E2no válido4(k1)no válido8(k1)
E3no válidono válidono válidono válido

Guarda lo siguiente como schedule-lab.mjs y ejecuta node schedule-lab.mjs. No requiere paquetes e imprime Schedule lab passed. Los tokens no válidos son null; los válidos transportan value y k. Este modelo de un único trabajo omite las etiquetas job, pero comprueba k explícitamente.

javascript
import assert from 'node:assert/strict';
const A=[[1,2],[3,4]],B=[[5,6],[7,8]],N=2,K=2;
const fresh=()=>({a:null,b:null,acc:0,count:0});
let grid=Array.from({length:N},()=>Array.from({length:N},fresh));
const expected=[[[5,0],[0,0]],[[19,6],[15,0]],
                [[19,22],[43,18]],[[19,22],[43,50]]];
const token=(value,k)=>({value,k});
for(let t=0;t<K+2*N-2;t++) {
 const next=grid.map(r=>r.map(p=>({...p})));
 for(let i=0;i<N;i++) for(let j=0;j<N;j++) {
  const ka=t-i,kb=t-j;
  const a=j?grid[i][j-1].a:(ka>=0&&ka<K?token(A[i][ka],ka):null);
  const b=i?grid[i-1][j].b:(kb>=0&&kb<K?token(B[kb][j],kb):null);
  const p=next[i][j];p.a=a;p.b=b;
  if(a&&b){assert.equal(a.k,b.k);assert.equal(a.k,p.count);
   p.acc+=a.value*b.value;p.count++;}
 }
 grid=next;
 assert.deepEqual(grid.map(r=>r.map(p=>p.acc)),expected[t]);
}
assert.deepEqual(grid.map(r=>r.map(p=>p.count)),[[2,2],[2,2]]);
console.log('Schedule lab passed');

Cada PE lee el estado anterior y escribe el siguiente. Iterar actualizando en el mismo lugar permitiría incorrectamente un reenvío de varios saltos en un solo flanco.

Después de E0, solo el acumulador de C(0,0) vale cinco. E1 lo completa en diecinueve e inicia sus vecinos en seis y quince. E2 completa estos en veintidós y cuarenta y tres, mientras que el último PE solo tiene dieciocho. E3 suma treinta y dos para producir cincuenta.

Cambia la inyección de fila de t−i a t. Una aserción de etiquetas debe detectar la desalineación. La finalización requiere cuatro flancos con avance y que todos los contadores sean iguales a dos. Se excluyen la inicialización y la transferencia de salida en serie. Este modelo ejecutable valida la planificación indicada sin afirmar ejecución RTL ni DDS.

RTL real: la cuadrícula 2×2 registrada

El adjunto systolic_2x2.sv conecta cuatro instancias de signed_mac_pe.sv, limitado a N=K=2. A se desplaza a la derecha y B hacia abajo por enlaces registrados que transportan valid y etiquetas k. El proveedor externo del borde realiza el desfase; la tarea step del banco de pruebas aplica directamente la planificación E0..E3. Clear termina antes de E0 y no hay segmentación adicional del multiplicador.

Guarda juntos los tres adjuntos y ejecuta Icarus Verilog:

bash
iverilog -g2012 -s tb_systolic_2x2 -o systolic.vvp signed_mac_pe.sv systolic_2x2.sv tb_systolic_2x2.sv
vvp systolic.vvp

Las matrices posteriores al flanco son [[5,0],[0,0]], [[19,6],[15,0]], [[19,22],[43,18]] y [[19,22],[43,50]]. Done se activa solo después de E3. Dos pausas dan cuatro flancos con avance y seis flancos físicos de cálculo. Las comprobaciones también cubren [[10,9],[−6,3]], la conservación completa del estado y el reinicio a mitad de trabajo. Espera RTL PASS:.

Como ejercicio de modificación RTL, sustituye un enlace registrado de operandos por un camino combinacional. Predice el primer fallo de alineación de etiquetas o suma intermedia, compara el registro y restaura el registro de hardware. Extender esta cuadrícula a N×N requiere revisar conjuntamente cableado, desfase, anchuras, etiquetas y finalización.

Inténtalo tú

Después de E2, ¿cuál es el acumulador de PE(1,1) y qué término queda? ¿Por qué cambia en E3 pese a las entradas de borde no válidas?

Leer la explicación

El acumulador vale 18 por 3×6, y queda 4×8=32. Esos operandos están en los registros internos de reenvío y llegan en E3; unos bordes no válidos no vacían instantáneamente la matriz.

Lesson files

schedule-lab.mjs ↓signed_mac_pe.sv ↓systolic_2x2.sv ↓tb_systolic_2x2.sv ↓

Tu elección se aplica a este navegador. Puedes cambiarla en el pie de página.