6 / 20 · Prática
Laboratório: elemento de processamento MAC com sinal
Use um modelo independente para verificar operandos válidos, pausas e clear.
As aulas podem ser lidas gratuitamente. Inscreva-se para salvar o progresso.
Execute o contrato de um PE
Salve este código como pe-lab.mjs e execute node pe-lab.mjs com Node.js. Ele não usa pacotes externos e imprime PE lab passed. Isso verifica um modelo de aritmética e controle; não compila SystemVerilog nem demonstra execução no DDS. Considere o trabalho comum de dois termos como W=8, K=2, AW=17, enquanto o modelo usa inteiros amplos em sua referência.
O PE recebe indicadores de validade separados para A e B. Ele acumula apenas quando ambos são verdadeiros. O encaminhamento segue o indicador de validade de cada operando. Uma aula posterior acrescenta etiquetas para garantir que dois operandos válidos pertençam ao mesmo termo de redução.
import assert from 'node:assert/strict';
const pe = {acc:0,a:0,b:0,av:false,bv:false};
function edge({a=0,b=0,av=false,bv=false,
advance=true,clear=false,reset=false}={}) {
if (reset || clear) {
Object.assign(pe,{acc:0,a:0,b:0,av:false,bv:false});
} else if (advance) {
if (av && bv) pe.acc += a*b;
Object.assign(pe,{a,b,av,bv});
}
return {...pe};
}
edge({clear:true});
assert.equal(edge({a:-2,b:3,av:true,bv:true}).acc,-6);
const held={...pe};
assert.deepEqual(edge({a:99,b:99,av:true,bv:true,advance:false}),held);
assert.equal(edge({a:4,b:-5,av:true,bv:true}).acc,-26);
assert.equal(edge({a:8,b:8,av:true,bv:false}).acc,-26);
assert.equal(pe.av,true); assert.equal(pe.bv,false);
edge({clear:true,a:100,b:100,av:true,bv:true});
assert.equal(pe.acc,0); assert.equal(pe.av,false);
assert.equal(edge({a:-128,b:-128,av:true,bv:true}).acc,16384);
edge({reset:true,advance:false});
assert.deepEqual(pe,{acc:0,a:0,b:0,av:false,bv:false});
console.log('PE lab passed');Preveja e desafie o resultado
O primeiro par produz −6. Uma pausa ignora os valores 99 oferecidos e mantém todo o estado. O próximo par válido contribui com −20, chegando a −26. O token A sem par é encaminhado, mas não contribui com um MAC. Clear prevalece sobre o par válido simultâneo; mínimo×mínimo então produz 16384. Reset limpa o estado de validade mesmo quando advance é falso.
Traduza a mesma prioridade para always_ff usando sinais de produto e parcela explicitamente com sinal. Ao modelar uma matriz, leia o estado anterior e escreva um próximo estado separado. Atualizar objetos de PE diretamente pode permitir acidentalmente que um token atravesse vários PEs durante uma borda.
Mude a condição de acumulação de AND para OR. A asserção do token sem par deve falhar. Tente também aplicar advance apenas ao acumulador, permitindo que o encaminhamento se mova. Explique qual contrato cada asserção protege; uma mensagem de aprovação por si só não é todo o objetivo de aprendizagem.
Registre os operandos oferecidos separadamente dos consumidos: os valores noventa e nove em pausa são visíveis na interface, mas nunca consumidos. O módulo envolvente deve manter o próximo termo programado até advance retomar. As cópias de estado retornadas preservam observações anteriores. Inspecione os indicadores de validade do encaminhamento além do acumulador ao traduzir essas verificações para um testbench baseado em formas de onda.
RTL real: o PE MAC com sinal
Salve os anexos signed_mac_pe.sv, systolic_2x2.sv e tb_systolic_2x2.sv juntos. Os dois primeiros arquivos são RTL sintetizável; o testbench é apenas para simulação. O PE estende o sinal de seu produto completo de 2W bits para AW antes da acumulação. As verificações W=8,K=4 usam AW=18 para 65536, −65024 e 64516. Etiquetas k ordenadas rejeitam termos divergentes por protocol_error.
A prioridade é reset, clear e depois advance. Clear termina antes da primeira borda de dados. Observe o acumulador atualizado após cada borda de subida; vizinhos consomem encaminhamento registrado na próxima borda com advance. Uma pausa mantém cada valor, indicador de validade, etiqueta e contagem. Um trabalho executa entre limpezas, sem quantização de saída nem integração DDS.
Com Icarus Verilog instalado, execute:
iverilog -g2012 -s tb_systolic_2x2 -o systolic.vvp signed_mac_pe.sv systolic_2x2.sv tb_systolic_2x2.sv
vvp systolic.vvpEspere RTL PASS:; falhas terminam com $fatal. Modifique addend para usar extensão com zeros e reproduza a falha da matriz negativa. Explique o primeiro acumulador de PE divergente, restaure a extensão de sinal e execute novamente. Mantenha logs de Node e HDL separados.
Experimente
Insira um par válido (0,7) entre (−2,3) e (4,−5). Qual é a soma e como um zero válido difere de um token inválido?
Ler a explicação
A soma é −26. Um zero válido ainda consome um termo k real e avança a contagem de termos e as etiquetas. Um token inválido não consome termo algum. Para um trabalho de três termos, atualize K, a análise de largura e o controle de conclusão de acordo.