Incluyendo un módulo en otro módulo con variable

0

Necesito implementar este código para sintetizar y hacerlo para que xor21 y and21 funcionen por separado.

module top(
 input a, b, x,
 output c
);

always @(a or b or x)
begin
    if(x)
       xor21 x1 (.a(a), .b(b), .c(c));
   else
      and21 a1 (.a(a), .b(b), .c(c));
end
endmodule

Sin embargo, me sale el siguiente error:

  

ERROR: HDLCompiler: 1575 No se permite la creación de instancias en el área secuencial   excepto la instanciación del verificador

¿Cómo hago para diseñar esto?

    

1 respuesta

4

Tienes que volver a lo básico.

Verilog es un lenguaje de descripción de hardware, no un lenguaje de programación. Su código describe hardware.

Veamos qué intenta deducir tu código:

module top(
 input a, b, x,
 output c
 );

Ok, tenemos un módulo. Eso está todo bien. Ahora, ¿qué hace?

always @(a or b or x)
begin
    if(x)
       xor21 x1 (.a(a), .b(b), .c(c));
   else
      and21 a1 (.a(a), .b(b), .c(c));
end

El código dice "Siempre que a , b o x cambie: Si x es alto, cree una nueva pieza de hardware llamada xor21 , de lo contrario, cree una instancia de otra pieza de hardware llamada and21 ".

Hmm, eso significa que si el valor de x cambia, los bits de su hardware desaparecen repentinamente, y otros bits de hardware aparecen de la nada. Esto no puede suceder . Todo el diseño debe conocerse cuando se sintetiza el diseño.

En otras palabras, no puede crear una instancia de un módulo en un bloque de procedimiento.

En su lugar, debe pensar qué hardware necesita. Tú decides, bueno, necesito un módulo and21 y un módulo xor21 . Así que vamos a crear una instancia de cada uno:

module top(
 input a, b, x,
 output c
 );

 wire xor21_output;
 wire and21_output;

 xor21 x1 (.a(a), .b(b), .c(xor21_output));
 and21 x1 (.a(a), .b(b), .c(and21_output));

Genial. Ahora tenemos un módulo nuestro, y contiene nuestros dos submódulos. Ahora necesitamos resolver el comportamiento de la salida c .

Bueno, si x es alto, queremos la salida de xor21 , y si x es bajo, necesitamos la salida de and21 . Eso significa que necesitamos un multiplexor. Bueno, podemos hacer esto en una asignación continua utilizando el operador ternario ( ? ), o podemos usar un bloque siempre. Echemos un vistazo a ambos. Primero el ternario:

assign c = x ? xor21_output : and21_output;

Luego el bloque siempre (ver nota):

always @ (x) begin
    if (x) begin
        c = xor21_output;
    end else begin
        c = and21_output; 
    end
end

Y voila. Ahora tenemos un módulo con el comportamiento requerido, en el que se conoce el hardware requerido cuando se sintetiza el diseño.

(nota): si está asignando un valor en un bloque de procedimiento (como siempre o inicial), el destino debe ser un tipo de almacenamiento, como reg . No puede asignar un tipo wire en un bloque de procedimiento. Entonces tendríamos que cambiar la definición del módulo a output reg c .

    
respondido por el Tom Carpenter

Lea otras preguntas en las etiquetas