Interrupção, marcador de fim e multiprocessador

Três recursos que aparecem quando o processador deixa de ser um exercício e vira parte de um sistema.

Interrupção: #PRACA

A diretiva #PRACA, colocada como um comando dentro de main(), marca o endereço de atendimento de interrupção e cria o pino itr no processador. Enquanto itr estiver em 1, o contador de programa salta para o ponto marcado; quando volta a 0, o programa retoma de onde estava.

Listagem 11 esqueleto com atendimento de interrupcao
void main()
{
    int amostra;

    while (1)
    {
        // laco principal
        amostra = in(0);
        out(0, amostra);

        #PRACA               // daqui em diante, o atendimento
        out(1, 1);           // sinaliza o evento na porta 1
    }
}

Só pode haver um #PRACA por programa. O uso típico: um periférico externo (o seu Verilog da Parte IV) levanta itr quando precisa de atenção, e o processador responde sem varrer a porta o tempo todo.

Marcador de fim: #TOAQUI

A diretiva #TOAQUI marca um endereço e cria o pino cheguei, que sobe quando o contador de programa passa por ali. É o mecanismo que o botão Teste do processador sintetizado usa para saber que o programa terminou: a AURORA injeta um #TOAQUI no final do main() automaticamente nesse fluxo.

Em um sistema seu, o pino serve de sincronização barata: “o processador chegou na fase tal”. Também só pode haver um por programa.

Multiprocessador

Vários processadores SAPHO convivem no mesmo projeto e no mesmo circuito. A receita é a da Parte IV, repetida:

  1. Crie cada processador no Hub, cada um com seu nome e seus parâmetros. Cada um vive na sua pasta, com seu .cmm.

  2. Compile cada um com Compilar C±. Ao usar os botões de síntese e simulação, a AURORA recompila todos os processadores do projeto antes, sozinha.

  3. Escreva um top-level Verilog que instancia todos e a lógica de interconexão: quem alimenta quem, quem sincroniza quem.

  4. O testbench do conjunto é seu. O testbench gerado automaticamente dirige um processador isolado; um sistema com dois ou mais pede um testbench que conheça a interconexão.

O padrão de interconexão mais comum é o produtor e consumidor: a porta de saída de um processador alimenta a porta de entrada do outro, com o aperto de mão out_en e req_in fazendo a sincronização, possivelmente com uma FIFO entre eles quando os ritmos diferem.

Estudo de caso: DTW com dois processadores

O repositório do YANC traz um sistema completo de detecção de novidade em sinais de 60 Hz usando dois processadores: um ZeroCross, que detecta cruzamentos de zero e segmenta o sinal, e um ProcDTW, que calcula a distância DTW contra um padrão. Uma máquina de estados em Verilog puro coordena os dois, e o conjunto foi validado em FPGA real.

Os fontes estão em Compilers/CMMComp/Tests/DTW do repositório do YANC: os dois .cmm, o top-level, a máquina de estados e o testbench do sistema. É o melhor material de estudo para o padrão multiprocessador.

O padrão multiprocessador tem literatura própria do laboratório: a arquitetura multi-core para reconstrução online de energia (CBA, 2020) e o simulador de pulsos do TileCal com SAPHO (SBAI, 2025), este rodando na eletrônica do experimento ATLAS.

Na onda, cada processador aparece com seu grupo de sinais e suas próprias trilhas de assembly e de linha C±, então dá para acompanhar os dois programas executando em paralelo, ciclo a ciclo.