Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Industrial programming >> Verilog

Dominar los parámetros en Verilog: Construir módulos reutilizables y escalables

Los parámetros son construcciones de Verilog que permiten que un módulo se reutilice con una especificación diferente. Por ejemplo, un sumador de 4 bits puede parametrizarse para aceptar un valor para el número de bits y nuevos valores de parámetros pueden pasarse durante la instanciación del módulo. Así, un sumador de N bits puede convertirse en un sumador de 4, 8 o 16 bits. Son como argumentos a una función que se pasan durante una llamada a función.

parameter MSB = 7;           // MSB es un parámetro con valor constante 7
parameter REAL = 4.5;        // REAL contiene un número real
parameter FIFO_DEPTH = 256, MAX_WIDTH = 32; // Declara dos parámetros
parameter [7:0] f_const = 2'b3; // Valor de 2 bits convertido a 8 bits; 8'b3

Los parámetros son básicamente constantes y por tanto es ilegal modificar su valor en tiempo de ejecución. Es ilegal redeclarar un nombre que ya se usa por una red, variable u otro parámetro.

Hay dos tipos principales de parámetros, module e specify y ambos aceptan una especificación de rango. Pero, normalmente se hacen tan anchos como el valor a almacenar requiere y por tanto una especificación de rango no es necesaria.

Parámetros de módulo

Los parámetros de módulo pueden usarse para sobrescribir definiciones de parámetros dentro de un módulo y esto hace que el módulo tenga un conjunto diferente de parámetros en tiempo de compilación. Un parámetro puede modificarse con la declaración defparam o en la declaración de instanciación del módulo. Es una práctica común usar letras mayúsculas en los nombres de los parámetros para hacerlos instantáneamente notables.

El módulo mostrado a continuación usa parámetros para especificar el ancho de bus, ancho de datos y la profundidad de FIFO dentro del diseño, y puede sobrescribirse con nuevos valores cuando el módulo se instancia o usando declaraciones defparam.

// Estilo de declaración de puertos Verilog 1995
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];
  // Código de diseño va aquí ...
endmodule

En el nuevo estilo ANSI de declaración de puertos de Verilog, puede declarar parámetros como se muestra a continuación.

module design_ip #(parameter BUS_WIDTH=32, parameter DATA_WIDTH=64) (
  input [BUS_WIDTH-1:0] addr,
  // Otras declaraciones de puertos
);

Sobrescribir parámetros

Los parámetros pueden sobrescribirse con nuevos valores durante la instanciación del módulo. La primera parte instancia el módulo llamado design_ip con el nombre d0 donde los nuevos parámetros se pasan dentro de #( ). La segunda parte usa una construcción de Verilog llamada defparam para establecer los nuevos valores de parámetros. El primer método es la forma más común de pasar nuevos parámetros en diseños RTL. El segundo método se usa comúnmente en simulaciones de testbench para actualizar rápidamente los parámetros del diseño sin tener que reinstanciar el módulo.

module tb;
  // Sobrescritura por instanciación de módulo
  design_ip #(BUS_WIDTH = 64, DATA_WIDTH = 128) d0 ([lista_puertos]);

  // Uso de defparam para sobrescribir
  defparam d0.FIFO_DEPTH = 128;
endmodule

Ejemplo

El módulo counter tiene dos parámetros N y DOWN declarados con valor por defecto de 2 y 0 respectivamente. N controla el número de bits en la salida controlando efectivamente el ancho del contador. Por defecto es un contador de 2 bits. El parámetro DOWN controla si el contador debe incrementar o decrementar. Por defecto, el contador decrementará porque el parámetro se establece en 0.

Contador ascendente de 2 bits

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)
        if (DOWN)
          out <= out - 1;
        else
          out <= out + 1;
      else
        out <= out;
    end
  end
endmodule

El módulo counter se instancia con N como 2 aunque no es requerido porque el valor por defecto es de todos modos 2. DOWN no se pasa durante la instanciación del módulo y por tanto toma el valor por defecto de 0 haciendo un contador ascendente.

module design_top (
  input clk,
  input rstn,
  input en,
  output [1:0] out
);
  counter #(.N(2)) u0 (
    .clk(clk),
    .rstn(rstn),
    .en(en)
  );
endmodule

Vea que se usan parámetros por defecto para implementar el contador donde N es igual a dos haciendo un contador de 2 bits y DOWN es igual a cero haciendo un contador ascendente. La salida del contador queda sin conectar en el nivel superior.

Contador descendente de 4 bits

En este caso, el módulo counter se instancia con N como 4 haciendo un contador de 4 bits. DOWN se pasa un valor de 1 durante la instanciación del módulo y por tanto se implementa un contador descendente.

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

Parámetros specify

Estos se usan principalmente para proporcionar valores de temporización y retardo y se declaran usando la palabra clave specparam. Se permite usarlos tanto dentro del bloque specify como en el cuerpo principal del módulo.

// Uso de bloque specify
specify
  specparam t_rise = 200, t_fall = 150;
  specparam clk_to_q = 70, d_to_q = 100;
endspecify

// Dentro del módulo principal
module my_block ( ... );
  specparam dhold = 2.0;
  specparam ddly = 1.5;
  parameter WIDTH = 32;
endmodule

Diferencia entre parámetros specify y de módulo

Parámetro specify Parámetro de módulo
Declarado por specparam Declarado por parameter
Puede declararse dentro de bloque specify o módulo principal Solo puede declararse dentro del módulo principal
Puede asignarse specparams y parámetros No puede asignarse specparams
SDF puede usarse para sobrescribir valores Valores de parámetros en declaración de instancia o defparam pueden usarse para sobrescribir

Verilog

  1. Dominar Verilog: Tutorial completo para diseño de circuitos digitales
  2. Dominar la concatenación en Verilog: Guía práctica
  3. Verilog Esencial: Resumen conciso
  4. Comprender las asignaciones en Verilog: tipos, sintaxis y mejores prácticas
  5. Bloqueante vs. No bloqueante en Verilog: Diferencias clave explicadas
  6. Dominar las funciones en Verilog para diseño RTL eficiente
  7. Comprender las Tasks en Verilog: Funciones vs Tasks, sintaxis y uso
  8. Dominar el alcance de referencia jerárquica en Verilog: Evitar colisiones de nombres en módulos y bloques
  9. Generador de reloj en Verilog: Guía de diseño e implementación
  10. Dominar las funciones matemáticas en Verilog para diseño de hardware eficiente
  11. Dominar $timeformat en Verilog: Control de precisión y visualización