Pergunta sobre loop for sintetizável e gerar

Estou usando a linguagem Verilog e o Zedboard como um tabuleiro de destino.

Até onde eu sei , o loop for pode ser sintetizado e a ferramenta de síntese traduz o loop for como uma sequência de instruções duplicadas, como o desenrolamento do loop.

Por exemplo,

for ( i = 0; i < 4; i=i+1) begin mem[i] = i; end will be translated to mem[0] = 0; mem[1] = 1; mem[2] = 2; mem[3] = 3; 

Portanto, até onde eu sei, o loop for pode ser usado se o recurso estiver disponível para inferir as portas múltiplas, mas com a mesma finalidade.

No entanto, parece que o gerar em Verilog pode ser usado para, não apenas implicar as várias instâncias, mas também as várias instruções, iguais ao loop for.

Eu entendo que o generate só pode implicar as várias instâncias do módulo e o loop for não pode ser usado para esse propósito.

Então, qual é a diferença entre o loop generate + for e apenas for? Acho que ambos funcionam como o desenrolamento do loop. Existe alguma diferença perceptível? Se não houver diferença, qual é o estilo de codificação preferível para induzir o desenrolamento do loop?

Comentários

  • Apenas para maior clareza, ' s: Quero dizer, você deduz. por exemplo. você implica uma RAM em Verilog / VHDL, o software de síntese infere essa RAM de seu Verilog / VHDL. Erro muito comum, vale a pena aprender.

Resposta

Os loops for Verilog são perfeitamente sintetizáveis sob certas condições:

  • Você pode usar qualquer instrução procedimental dentro de um loop (por exemplo, if-else).
  • O número de loops deve ser predeterminado .
    • A expressão limitante deve ser uma comparação entre a variável do loop e uma constante ou um parâmetro.
    • A atribuição da etapa deve incrementar o valor do loop em uma quantidade constante.
  • Você pode atribuir um valor diferente à mesma variável em cada loop (por exemplo, calculando um índice da variável de loop).
  • Para fins de síntese, o loop é avaliado em tempo zero – ou seja, se você tentar fazer um contador, verá apenas o valor final.

Essas mesmas regras se aplicam se você usar um loop for em um bloco procedural ou em um bloco de geração.

Quando feito em um bloco de procedimento, initial e always, você pode usar um for loop para alterar elementos em uma matriz (exatamente como seu exemplo), ou você pode alterar o mesmo valor várias vezes, por exemplo:

for (idx = 0; idx < 4; idx=idx+1) begin a = a + b[idx]; c = c + 2; //You can change more than one variable in a for loop end 

Nesse exemplo, o hardware resultante será uma cadeia de somadores, somando os valores de quatro índices de matriz.

O principal é que você não pode “criar novas variáveis ou módulos em um loop for procedural. Esta regra se aplica a blocos procedurais em geral, não apenas para loops (ou seja, você não pode “declarar uma variável em um bloco procedural).

 

Por outro lado, blocos de geração permitem a criação de variáveis e a instanciação de módulos. Isso significa que em um bloco de geração, você pode usar um loop de geração para inferir módulos. Essa é praticamente a única diferença.

Para gerar loops for, você deve usar um genvar como a variável do loop (ou seja, o valor que você usa para contar em cada loop). Você também deve dar um nome ao loop for:

for (loopVal = 0; loopVal < 4; loopVal = loopVal + 1) begin : loopName 

Este nome é anexado a qualquer peça de hardware que você instanciar no loop. Portanto, se você criar uma instância chamada bob, o loop acima criará instâncias:

loopName[0]|bob loopName[1]|bob loopName[2]|bob loopName[3]|bob 

Isso resulta em vários instâncias com nomes únicos.

 

Ambos os loops for de geração e procedimento realizarão o desenrolamento do loop como você diz. A diferença é simplesmente como você pode usá-los. Os procedimentos podem ser usados em blocos de procedimentos (por exemplo, para inicializar uma memória). Generate só pode ser usado em blocos de geração.

Eles são úteis e preferidos. Um não pode substituir o outro.

Comentários

  • outra maneira de pensar em generate é como uma espécie de pré-processador, seu compilador verilog ' executa ' coisas em blocos de geração no ponto em que ' instancia o bloco contendo os gera – eles não ' acontecem em tempo de execução (ao contrário de loops procedurais)
  • @Taniwha loops procedurais don ' t executar em tempo de execução também. Eles são desenrolados pelo compilador. Tudo se resume ao hardware no final. Também não ' t confunda o pré-processador com comandos de geração, eles não são o mesmo conceito – Verilog tem um pré-processador incluindo instruções do tipo if-else.
  • @TomCarpenter Agradeço uma ótima resposta. Eu poderia entender todos os seus pontos, exceto o loop generate for.Parece que begin: something deve ser adicionado logo antes do loop for, mas não consigo entender como funciona na instanciação de módulos. O loopName é uma variável ou apenas uma string? E como eles podem ser indexados por [1] a [4].
  • @JaeHyukLee loopName é apenas texto, como um nome de instância ou um nome de sinal. Pode ser o que você quiser.
  • @TomCarpenter – depende do compilador – se você ' recompilar portas sim, elas são desenroladas, se você ' recompilar código para simulação provavelmente não (isenção de responsabilidade, eu ' escrevi um compilador Verilog)

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *