23 / 24 · Práctica
Proyecto final: pequeña ruta de inferencia e informe
Mantén K=9,cuatro salidas y un ciclo adicional por salida, pero usa tres PE. ¿Cuáles son los ciclos modelados totales y la utilización de posiciones solo de MAC?
Las lecciones se pueden leer gratis. Inscríbete para guardar el progreso.
Objetivo y criterios de aceptación
Conserva model.mjs de la práctica anterior,crea capstone-lab.mjs junto a él y ejecuta node capstone-lab.mjs. Conecta una capa de convolución,sesgo,recuantización,ReLU y agrupación máxima. Informa de los valores por separado del coste. No es un clasificador completo ni un motor de entrenamiento. Puedes inspeccionar manualmente los archivos mediante un flujo de archivos admitido de Digital Design Studio instalado; no se acredita ejecución dentro de DDS.
Termina cuando concuerden los acumuladores de convolución directa y de productos escalares de parches,coincidan los datos intermedios y de salida y tu informe incluya dimensiones,MAC,ciclos supuestos,utilización de posiciones y bytes únicos de tensores. Añade un caso de entrada modificada calculado independientemente a mano. Conserva el comando,la versión del archivo y los supuestos junto al registro. Investiga una comparación fallida en lugar de limitarte a modificar su valor esperado.
Referencia resuelta
La entrada es 4×4 con valores de 1 a 16. El núcleo [1,0,−1;1,0,−1;1,0,−1] resta la muestra derecha de la izquierda en cada fila. Cada fila da −2, así que toda ventana suma −6. El sesgo ocho da cuatro acumuladores iguales a dos. El multiplicador 0.5 y el punto cero cero producen el código uno. ReLU lo conserva y la agrupación 2×2 da [1]. Conserva también datos asimétricos de bordes; salidas iguales pueden ocultar errores de orden.
Las dimensiones [M,Ho,Wo] son [1,2,2]. Cuenta 36 MAC,incluidos términos de pesos cero. Con dos PE de una MAC que comparten la reducción de cada salida,supón cinco ciclos MAC más uno de combinación/escritura por salida,sin solapamiento ni detenciones. El total modelado es 24 ciclos. La utilización de posiciones solo de MAC es 36/(4×5×2)=90%. No es latencia medida de un dispositivo.
Los tensores únicos int8 usan entrada 16,pesos 9 y salidas de convolución 4 bytes,más un sesgo de cuatro bytes. La salida agrupada usa un byte. El tráfico real puede incluir recargas y sumas parciales. Las escalas sx=sw=1, sy=2 explican el multiplicador 0.5.
Cambiar el sesgo a cero predice acumulador −6,código −3,activado cero y agrupado cero. Cambiar solo la primera entrada de uno a dos da primer acumulador tres,empate 1.5 redondeado a dos,tres salidas restantes uno y agrupado dos. Prueba los cambios por separado. Más PE u omitir pesos cero requiere una nueva planificación explícita que conserve los valores.
Archivo ejecutable
import assert from 'node:assert/strict';
import {conv2d, im2col, dot, requantize, maxPool2x2} from './model.mjs';
const x = [Array.from({length: 4}, (_, r) => Array.from({length: 4}, (_, c) => r * 4 + c + 1))];
const kernel = [[1, 0, -1], [1, 0, -1], [1, 0, -1]];
const weights = [[kernel]], bias = [8];
const reference = conv2d(x, weights, {bias});
const flattenedWeights = kernel.flat();
const rows = im2col(x, 3, 3);
const accumulators = rows.map(row => dot(row, flattenedWeights) + bias[0]);
assert.deepEqual(accumulators, reference[0].flat());
assert.deepEqual(accumulators, [2, 2, 2, 2]);
const activated = reference[0].map(row => row.map(v => Math.max(0, requantize(v, 0.5))));
const pooled = maxPool2x2(activated);
assert.deepEqual(activated, [[1, 1], [1, 1]]);
assert.deepEqual(pooled, [[1]]);
// Cycle estimate with explicit assumptions: all MAC operands local, no stalls,
// one output at a time, K=9, two single-MAC PEs, no overlap with output write.
const macs = rows.length * flattenedWeights.length;
const peCount = 2, macCyclesPerOutput = Math.ceil(flattenedWeights.length / peCount);
const modelCycles = rows.length * (macCyclesPerOutput + 1);
const usefulSlots = macs, scheduledSlots = rows.length * macCyclesPerOutput * peCount;
assert.equal(macs, 36);
assert.equal(modelCycles, 24);
assert.equal(usefulSlots / scheduledSlots, 0.9);
const report = {shape:[1, 2, 2], accumulators, activated, pooled, macs, peCount,
modelCycles, macSlotUtilization:usefulSlots / scheduledSlots,
uniqueInputBytes:16, weightBytes:9, outputBytes:4, biasBytes:4,
scope:'Software reference and schedule estimate only; no synthesis or DDS run'};
console.log(JSON.stringify(report, null, 2));Proyecto final RTL: convolución entera
Los adjuntos cnn_window3x3.sv y cnn_conv3x3.sv conectan las ventanas a nueve productos 8×8 con signo, una suma/sesgo de 24 bits con signo, división por dos con redondeo al más cercano y desempate al par, saturación int8, ReLU y un máximo 2×2. La geometría es el contrato anterior 4×4, de un canal y 3×3 sin relleno. Las escalas de entrada/pesos son uno, la de salida dos y todos los puntos cero son cero. El núcleo predeterminado es [1,0,−1;1,0,−1;1,0,−1], con sesgo ocho. Los parámetros de núcleo pueden cambiar; revisa la cota de suma de 24 bits.
Compara out_acc, out_code y out_activation por separado, con out_row/out_col y transferencias de salida aceptadas. done sube después de aceptar el cuarto resultado; entonces pooled es válido. Dieciséis entradas aceptadas no implican finalización. Este RTL usa nueve productos paralelos y dos etapas registradas, en lugar de la estimación anterior de dos PE y 24 ciclos. Frecuencia/potencia requieren síntesis o pruebas del dispositivo.
Ejecuta el banco compartido con autocomprobación:
iverilog -g2012 -s tb_cnn_stream -o cnn-sim cnn_window3x3.sv cnn_conv3x3.sv tb_cnn_stream.sv
vvp cnn-simLos acumuladores predeterminados son dos, los códigos/activaciones uno y la salida agrupada uno. Las comprobaciones incluyen límites con signo, saturación, empates positivos/negativos, un núcleo denso con signo, pausas y reinicio. Verifica PASS frames=6 windows=24 outputs=24 kernels=2 en tu registro real. Cambia la primera entrada a dos: la primera suma tres se redondea al código dos y la agrupada pasa a dos. Después elige otro núcleo con signo, calcula a mano su primera ventana, actualiza la función independiente de coeficientes y vuelve a ejecutar todos los datos de prueba. No copies resultados del DUT al modelo de referencia.
Inténtalo tú
Mantén K=9,cuatro salidas y un ciclo adicional por salida, pero usa tres PE. ¿Cuáles son los ciclos modelados totales y la utilización de posiciones solo de MAC?
Leer la explicación
Cada salida necesita tres ciclos MAC más uno adicional, así que el total es dieciséis. Las 36 posiciones MAC son útiles, lo que da 100%. La igualdad de frecuencia,suministro y coste de combinación sigue requiriendo pruebas de implementación independientes.