Instanciando componentes parametricamente
Posted on seg 02 setembro 2019 in vhdl • 5 min read
Em muitas situações, não sabemos de antemão quantas instâncias de determinado componente precisaremos pois este número é parametrizável. Em VHDL, há a construção generate
que permite instanciar componentes e fazer ligações para as instâncias de modo programático, dependendo de um parâmetro. A única restrição para que esta construção seja sintetizável é que todos os parâmetros sejam resolvíveis no momento da síntese.
Sintaxe
1 2 3 |
|
Onde nome
é opcional e pode ser um nome qualquer para este for-generate. O parametro
é o nome do parâmetro que irá variar dentro do laço, assumindo os valores da lista
, e as primitivas concorrentes são as que serão instanciadas parametricamente (usando o parâmetro definido no laço).
O parâmetro deve ser algo resolvível pois o sintetizador irá substituir as primitivas concorrentes por várias cópias das mesmas primitivas, variando o parâmetro. A idéia é que o projetista possa instanciar várias instâncias do mesmo componente de uma só vez. Com o exemplo, a utilização ficará mais clara, então vamos lá!
Exemplo
Suponha que tenhamos a seguinte descrição de um flip-flop tipo D:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
Para fazer um registrador simples com $n$ bits baseado neste flip-flop, devemos montar a seguinte estrutura:
Em VHDL, a estrutura base deste registrador (parametrizável), fica como abaixo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
Observe o generate
na arquitetura. A linha ffs: ffd port map(clock, d(i), reset, q(i));
instanciará $n$ flip-flops, cada um ligado em um fio dos vetores (conjunto de fios) d
e q
, mas compartilhando o mesmo clock e reset. O fio do vetor que cada instância usará depende do parâmetro i
, que irá variar de n-1
até 0
.
Note que o nome da instância não leva índice e fica só como ffs
. Cada sintetizador tem uma maneira de diferenciar as instâncias, mas a maioria deles colocará algum tipo de índice na instância. Quando formos usar este registrador, se setarmos o parâmetro n
como 4 durante a instanciação, o sintetizador instanciará quatro flip-flops, chamados por exemplo de ffs_3
, ffs_2
, ffs_1
e ffs_0
. De fato, o código acima será transformado em algo similar a:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
A única diferença é que o sintetizador é quem fará o "desenrolamento" do laço for-generate, permitindo que o projetista descreva um hardware genérico cujo tamanho não é conhecido.
Condicionando o for-generate
Quando a estrutura é regular como no caso do registrador, o for-generate é muito útil e simples de usar. Mas e se houver pequenas diferenças? Para isso, há o if-generate, cuja sintaxe é:
1 2 3 |
|
Este tipo de if só pode ser usado dentro de um for-generate e serve justamente para fazer pequenas mudanças na estrutura do hardware sendo descrito, sem abrir mão da parametrização. Vejamos novamente um exemplo.
Exemplo
Considere o half-adder (ha
) e o full-adder (fa
) abaixo:
1 2 3 4 5 6 7 8 9 10 11 12 |
|
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Um somador simples de $n$ bits tem a seguinte estrutura:
Note que o primeiro componente é um half-adder e não possui entrada de carry, enquanto todos os demais possuem. Usando somente um for-generate este tipo de construção se torna complicada, inviabilizando sua utilização. Porém, com o uso do if-generate, podemos quebrar a regularidade do for-generate somente para alguns elementos selecionados, como na descrição do somador abaixo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
|
Dentro do for-generate temos dois if-generates: um para o bit menos significativo do somador, que onde deve ser usado um ha
(sem entrada de carry) e outro para os demais bits, onde deve ser usado um fa
com os carries sendo ligados sequencialmente. Este tipo de construção chama-se carry propagation ou ripple carry.
Da mesma forma que o anterior, para um somador de quatro bits, o sintetizador "desenrolará" o for-generate em (declaração dos componentes suprimida):
1 2 3 4 5 6 7 8 9 |
|
Resumo
O for-generate, aliado ao if-generate é uma poderosa ferramenta para descrever hardware parametrizável em VHDL, pois não sabemos no momento da descrição qual o valor do parâmetro. É muito usado para estruturas regulares ou com pouca variação. É possível usar outros tipos de primitivas concorrentes dentro do for-generate que não sejam a instanciação de componentes, e é possível até mesmo aninhar for-generates para instanciar matrizes de componentes, por exemplo.