O processador dentro do seu Verilog¶
Até aqui os dois mundos andaram separados: Verilog escrito à mão na Parte II, processador gerado na Parte III. Este capítulo os junta: o processador vira um componente dentro de um circuito seu.
É o arranjo típico de um projeto real: o processador cuida do algoritmo, e a lógica em volta cuida do resto, como interfaces, sincronização e pré-processamento.
As portas do processador gerado¶
Abra Hardware/media_movel.v e olhe o cabeçalho do módulo. As portas que ele expõe:
Porta |
Direção |
Largura |
Papel |
|---|---|---|---|
|
entrada |
1 |
clock |
|
entrada |
1 |
reset síncrono |
|
entrada |
|
dado de entrada |
|
saída |
|
dado de saída |
|
saída |
depende das portas |
qual porta de entrada o programa está lendo agora |
|
saída |
depende das portas |
qual porta de saída o programa está escrevendo agora |
O aperto de mão é simples: quando o programa executa in(k), o processador expõe k em req_in e espera o dado presente em in; quando executa out(k, v), expõe k em out_en e v em out por um ciclo. Com uma porta só, req_in e out_en funcionam como sinais de “lendo agora” e “válido agora”.
Dica
O melhor guia de fiação é o testbench gerado, Simulation/media_movel_tb.v: ele mostra exatamente como alimentar in em função de req_in e quando capturar out. Copiar a fiação dele para o seu top-level é o caminho seguro.
Um top-level de exemplo¶
Um gerador de estímulo em Verilog alimentando o filtro do tutorial: um contador produz uma rampa, e o processador devolve a média móvel dela.
1module top_filtro (
2 input wire clk,
3 input wire rst,
4 output wire [15:0] media,
5 output wire media_valida
6);
7
8 // gerador de estimulo: uma rampa que sobe de 8 em 8
9 reg [15:0] rampa;
10 wire lendo;
11
12 always @(posedge clk) begin
13 if (rst)
14 rampa <= 16'd0;
15 else if (lendo)
16 rampa <= rampa + 16'd8;
17 end
18
19 // o processador gerado pela Parte III
20 media_movel u_filtro (
21 .clk (clk),
22 .rst (rst),
23 .in (rampa),
24 .out (media),
25 .req_in (lendo),
26 .out_en (media_valida)
27 );
28
29endmodule
Passos na AURORA:
Crie
top_filtro.vno projetoMeuFiltro(a classificação o marcará como sintetizável).Botão direito, Definir como Top Level. O processador deixa de ser o topo e vira um componente.
Clique em Sintetizar Verilog. A elaboração resolve o módulo
media_movelsozinha, porque o.vgerado está no projeto.Escreva um testbench para o
top_filtro(clock, reset,$dumpvars,$finish), marque como Testbench Top e clique em Analisar Verilog.
Na onda, você verá a rampa entrando, o aperto de mão pulsando e a média saindo suavizada: dois mundos no mesmo diagrama de tempo.
Aviso
O processador carrega as memórias por $readmemb com os arquivos .mif. Recompile o C± antes de simular o conjunto, para as imagens de memória estarem atualizadas com o programa.
Hierarquia e PRISM¶
Com o top-level seu, a visão Hierarquia mostra o processador como uma instância entre as outras, e o PRISM desenha o conjunto: sua lógica e o processador no mesmo diagrama, cada um navegável.
Vários processadores no mesmo projeto seguem a mesma receita: crie cada um no Hub, compile cada um, e instancie todos no seu top-level. Um estudo de caso completo com dois processadores sincronizados está em Interrupção, marcador de fim e multiprocessador.
Exercícios¶
Troque a rampa por um gerador pseudoaleatório (um LFSR de 16 bits) e observe o filtro suavizando o ruído.
Insira um decimador entre o gerador e o processador: só uma a cada duas amostras chega ao filtro.
Coloque dois processadores em cascata: a saída do filtro de média alimenta um segundo processador que detecta quando o valor cruza um limiar e publica 0 ou 1.
Falta só um passo para o hardware de verdade: Levar ao FPGA.