System-verilog genera instancias de módulo y pasa datos de entrada / proceso de salida

1

Escribí un módulo en System Verilog, necesito 32 módulos, así que estoy usando generar declaración para crear instancias.

El problema es que en cada flanco ascendente del reloj necesito instanciar nuevos valores a los módulos y luego debo elegir uno de ellos (en el mismo posedge clock , dependiendo de las salidas de los módulos, en mi caso el min entre todas las salidas del módulo).

¿Cómo puedo hacer eso?

Esta es mi versión actual del código:

    genvar j; 
    generate 
        for (int j=0; j<32; j++)
         begin: module_instant_loop
            always @(posedge Clock)
               begin
                  MyUnit unit[j] (.A(TEST1[j],.B(TEST2[j]),.OUT(MYOUT[j]);
               end              
            end
         end
    endgenerate

Y este es el código que quiero agregar:

for (int i=0; i<32; i++)
    begin
        if (MYOUT[i] < MINIMUM) MINIMUM=MYOUT[i];
        if (MYOUT[i] > MAXIMUM) MAXIMUM=MYOUT[i];
    end

¿Cómo puedo agregar el bucle a mi código?

    
pregunta Matt. St

1 respuesta

2

No puede crear una instancia de un módulo dentro de un bloque siempre. Las opciones son mover la lógica síncrona dentro de MyUnit o cambiar la salida MyUnit al mismo nivel.

Por lo general, quieres cambiar tus resultados finales. Puede poner algo de lógica combinacional después del flop, pero tenga en cuenta que esto puede hacer que la sincronización flop-to-flop entre diferentes módulos sea más difícil de calcular.

Entonces, asumiendo que MINIMUM y MAXIMUM son los valores que desea fracasar, recomendaría la siguiente lógica:

always_comb begin
  // Set defaults
  next_MINIMUM = '1; // fill with all 1s
  next_MAXIMUM = '0; // fill with all 0s

  // Alternative default with the previous MIN/MAX values
  //next_MINIMUM = MINIMUM;
  //next_MAXIMUM = MAXIMUM;

  // Update MIN/MAX based on MYOUT
  foreach(MYOUT[idx]) begin // IEEE Std 1800-2012 12.7.3 The foreach-loop
    if (MYOUT[idx] < next_MINIMUM) next_MINIMUM=MYOUT[idx];
    if (MYOUT[idx] > next_MAXIMUM) next_MAXIMUM=MYOUT[idx];
  end
end

always_ff @(posedge clk) begin
  MINIMUM <= next_MINIMUM;
  MAXIMUM <= next_MAXIMUM;
end

Es una buena práctica asignar siempre un flop sin bloqueo. Se necesitan asignaciones de bloqueo para calcular correctamente el siguiente valor. Por lo tanto, las señales intermedias next_* . Cuando se utiliza SystemVerilog, se recomienda usar always_comb y always_ff en lugar de always (consulte IEEE Std 1800-2012 § 9.2.2.2.2 always_comb comparado con always @ * ).

    
respondido por el Greg

Lea otras preguntas en las etiquetas