No Verilog, os parâmetros são constantes e não pertencem a nenhum outro tipo de dados, como registros ou tipos de dados de rede.
Uma expressão constante refere-se a um número constante ou parâmetro definido anteriormente. Não podemos modificar valores de parâmetros em tempo de execução, mas podemos modificar um valor de parâmetro usando o comando defparam declaração.
O defparam instrução pode modificar parâmetros apenas no momento da compilação. Os valores dos parâmetros podem ser modificados usando # especificação de atraso com instanciação do módulo.
Em Verilog , existem dois métodos para substituir um valor de parâmetro de módulo durante uma instanciação de módulo.
- Usando a palavra-chave defparam.
- E atribuição de valor de parâmetro de instância de módulo.
Após a palavra-chave defparam, o caminho hierárquico é especificado para o parâmetro e o novo valor do parâmetro. Este novo valor deve ser uma expressão constante. Se a expressão do lado direito fizer referência a algum parâmetro, ela deverá ser declarada dentro do módulo onde defparam é invocado.
O método de atribuição de valor de parâmetro de instância de módulo parece uma atribuição de atraso à instância de portão. Este método substitui os parâmetros dentro dos módulos instanciados conforme aparecem no módulo. Usando este formato, os parâmetros não podem ser ignorados.
Expressões constantes podem conter parâmetros previamente declarados. Quando são detectadas alterações nos parâmetros declarados anteriormente, todos os parâmetros que dependem deste valor são atualizados automaticamente.
Considere que um somador de 4 bits pode ser parametrizado para aceitar um valor para o número de bits e novos valores de parâmetros podem ser passados durante a instanciação do módulo. Portanto, um somador de N bits é convertido em um somador de 4, 8 ou 16 bits. Eles são como argumentos para uma função passada durante uma chamada de função.
parameter MSB = 7; // MSB is a parameter with the constant value 7 parameter REAL = 4.5; // REAL holds the real number parameter FIFO_DEPTH = 256, MAX_WIDTH = 32; // Declares two parameters parameter [7:0] f_const = 2'b3; // 2 bit value is converted into 8 bits; 8'b3
Existem dois tipos de parâmetros, módulo e especificamos e ambos aceitam uma especificação de intervalo. Porém, eles são tão amplos quanto o valor a ser armazenado e, portanto, uma especificação de intervalo não é necessária.
Parâmetros do módulo
Ele pode ser usado para substituir definições de parâmetros dentro de um módulo e fazer com que o módulo tenha um conjunto diferente de parâmetros em tempo de compilação. Um parâmetro pode ser modificado com o defparam declaração. É comum usar letras maiúsculas nos nomes para que o parâmetro os perceba instantaneamente.
O módulo abaixo usa parâmetros para especificar a largura do barramento, a largura dos dados e a profundidade do FIFO dentro do design e pode ser substituído por novos valores quando o módulo é instanciado ou usando instruções defparam.
module design_ip ( addr, wdata, write, sel, rdata); parameter BUS_WIDTH = 32, DATA_WIDTH = 64, FIFO_DEPTH = 512; input addr; input wdata; input write; input sel; output rdata; wire [BUS_WIDTH-1:0] addr; wire [DATA_WIDTH-1:0] wdata; reg [DATA_WIDTH-1:0] rdata; reg [7:0] fifo [FIFO_DEPTH]; endmodule
No novo estilo ANSI de declaração de porta Verilog, podemos declarar parâmetros como:
module design_ip #(parameter BUS_WIDTH=32, parameter DATA_WIDTH=64) (input [BUS_WIDTH-1:0] addr, // other port declarations );
Substituindo parâmetros
Os parâmetros podem ser substituídos por novos valores durante a instanciação do módulo. A primeira parte é o módulo chamado design_ip pelo nome d0 onde novos parâmetros são passados dentro de # ( ).
A segunda parte é usar uma construção Verilog chamada defparam para definir os novos valores dos parâmetros. O primeiro método é comumente usado para passar novos parâmetros em projetos RTL. E o segundo método é usado em simulações de testbench para atualizar rapidamente os parâmetros de projeto sem a necessidade de reinstanciar o módulo.
module tb; // Module instantiation override design_ip #(BUS_WIDTH = 64, DATA_WIDTH = 128) d0 ( [port list]); // Use of defparam to override defparam d0.FIFO_DEPTH = 128; endmodule
O contador do módulo possui dois parâmetros N e ABAIXO , que é declarado como tendo um valor padrão de 2 e 0.
N controla o número de bits na saída, controlando efetivamente a largura do contador. É um contador de 2 bits por padrão.
Parâmetro ABAIXO controla se o contador deve aumentar ou diminuir. O contador diminuirá porque o parâmetro está definido como 0.
Contador ascendente de 2 bits
thread.destroy
module counter # ( parameter N = 2, parameter DOWN = 0) (input clk, input rstn, input en, output reg [N-1:0] out); always @ (posedge clk) begin if (!rstn) begin out <= 0; end else begin if (en) (down) out <="out" - 1; + endmodule pre> <p>The module counter is instantiated with <strong> <em>N</em> </strong> as 2 even though it is not required because the default value is anyway 2.</p> <p> <strong> <em>DOWN</em> </strong> is not passed during module instantiation. And it takes the default value of 0 making it an up-counter.</p> <pre> module design_top (input clk, input rstn, input en, output [1:0] out); counter #(.N(2)) u0 (.clk(clk), .rstn(rstn), .en(en)); endmodule </pre> <p>The default parameters are used to implement the counter where <strong> <em>N</em> </strong> equals two, making it a 2-bit counter, and <strong> <em>DOWN</em> </strong> equals zero, making it an up-counter. The output from the counter is left unconnected at the top level.</p> <img src="//techcodeview.com/img/verilog-tutorial/47/verilog-parameters.webp" alt="Verilog Parameters"> <p> <strong>4-bit down Counter</strong> </p> <p>In this case, the module counter is instantiated with N as 4 making it a 4-bit counter. DOWN is passed a value of 1 during the module instantiation and hence a down-counter is implemented.</p> <pre> module design_top (input clk, input rstn, input en, output [3:0] out); counter #(.N(4), .DOWN(1)) u1 (.clk(clk), .rstn(rstn), .en(en)); endmodule </pre> <br> <img src="//techcodeview.com/img/verilog-tutorial/47/verilog-parameters-2.webp" alt="Verilog Parameters"> <h3>Specify Parameters</h3> <p>These parameters are used to provide time and delay values and declared using the <strong> <em>specparam</em> </strong> keyword. It is allowed to use both within the specified block and the main module body.</p> <pre> // Use of specify block Specify specparam t_rise = 200, t_fall = 150; specparam clk_to_q = 70, d_to_q = 100; endspecify // Within main module module my_block ( ); specparam dhold = 2.0; specparam ddly = 1.5; parameter WIDTH = 32; endmodule </pre> <h3>Difference between Specify and Module Parameters</h3> <table class="table"> <tr> <th>Specify parameter</th> <th>Module parameter</th> </tr> <tr> <td>Specify the specparam keyword declares parameter.</td> <td>The module parameter is declared by parameter.</td> </tr> <tr> <td>It can be declared inside a specific block or within the main module.</td> <td>It can only be declared within the main module.</td> </tr> <tr> <td>This parameter may be assigned specparams and parameters.</td> <td>This may not be assigned specparams.</td> </tr> <tr> <td>SDF can be used to override values.</td> <td>Instance declaration parameter values or defparam can be used to override.</td> </tr> </table> <p> <strong>Notes</strong> </p> <p>Here are some important notes for the Verilog parameters, such as:</p> <ul> <li>If we are using the <strong> <em>defparam</em> </strong> statement, we must specify a hierarchical path to the parameter.</li> <li>We cannot skip over a parameter in a <strong> <em>module instance parameter value assignment</em> </strong> . If we need to do this, use the initial value for a not overwritten parameter.</li> <li>When one parameter depends on the other, then the second will automatically be updated if we change the first one.</li> </ul> <hr></=>
Os parâmetros padrão são usados para implementar o contador onde N é igual a dois, tornando-o um contador de 2 bits, e ABAIXO é igual a zero, tornando-o um contador crescente. A saída do contador permanece desconectada no nível superior.
Contador decrescente de 4 bits
Neste caso, o contador do módulo é instanciado com N como 4, tornando-o um contador de 4 bits. DOWN recebe o valor 1 durante a instanciação do módulo e, portanto, um contador decrescente é implementado.
module design_top (input clk, input rstn, input en, output [3:0] out); counter #(.N(4), .DOWN(1)) u1 (.clk(clk), .rstn(rstn), .en(en)); endmodule
Especifique os parâmetros
Esses parâmetros são usados para fornecer valores de tempo e atraso e declarados usando o specparam palavra-chave. É permitido usar tanto dentro do bloco especificado quanto no corpo do módulo principal.
// Use of specify block Specify specparam t_rise = 200, t_fall = 150; specparam clk_to_q = 70, d_to_q = 100; endspecify // Within main module module my_block ( ); specparam dhold = 2.0; specparam ddly = 1.5; parameter WIDTH = 32; endmodule
Diferença entre parâmetros de especificação e de módulo
Especifique o parâmetro | Parâmetro do módulo |
---|---|
Especifique o parâmetro declara a palavra-chave specparam. | O parâmetro do módulo é declarado por parâmetro. |
Pode ser declarado dentro de um bloco específico ou dentro do módulo principal. | Só pode ser declarado dentro do módulo principal. |
Este parâmetro pode receber especificações e parâmetros atribuídos. | Isso não pode receber especificações. |
SDF pode ser usado para substituir valores. | Valores de parâmetro de declaração de instância ou defparam podem ser usados para substituir. |
Notas
Aqui estão algumas notas importantes para os parâmetros Verilog, como:
- Se estivermos usando o defparam instrução, devemos especificar um caminho hierárquico para o parâmetro.
- Não podemos pular um parâmetro em um atribuição de valor de parâmetro de instância de módulo . Se precisarmos fazer isso, use o valor inicial para um parâmetro não substituído.
- Quando um parâmetro depende do outro, o segundo será atualizado automaticamente se alterarmos o primeiro.
=>