¿Es posible manejar una red desde dos procesos cuando las asignaciones son condicionalmente mutuamente excluyentes?

1

En mi experiencia, manejar una red desde dos procesos separados (o siempre bloques) es una mala idea y dará como resultado un error de varios controladores en las herramientas.

Sin embargo, uno de mis conocidos afirma que si las asignaciones de señal están contenidas dentro de las declaraciones if que nunca afirman al mismo tiempo, debería ser posible controlar una señal desde dos bloques siempre.

Como prueba, hice esto en Vivado 2014.4. Aquí está mi código de prueba muy trivial:

// always block one
always @ (posedge clk) begin 
   if (rst) begin 
      RegA <= 0;
   end 
   else begin 
      if (RegA_in_valid_1) begin 
         RegA <= RegA_in_1;
      end 
   end 
end 

// Always block two
always @ (posedge clk) begin
   if (rst == 0) begin
      if (!RegA_in_valid_1 && RegA_in_valid_2)
        RegA <= RegA_in_2;
   end
end

Como esperaba, Vivado produce errores:

[Synth 8-3352] multi-driven net RegA_out_OBUF[31] with 1st driver pin 'RegA_reg[31]__0/Q' 
...

Después de esta prueba, dicho conocido aún afirma que este código se sintetizaría en versiones anteriores de Vivado sin errores. Esto me hizo pensar: ¿qué utiliza la herramienta de síntesis para determinar si una red tiene múltiples motores? ¿Utiliza las respectivas listas de sensibilidad, o este mecanismo es factible (usando declaraciones condicionales)? Veo que mi versión de Vivado no funciona, pero ¿cuál es el consenso en general?

    
pregunta stanri

1 respuesta

2

Si algunas ramas en el proceso no están explícitamente asignando algo de red, implícitamente se asigna con el valor anterior con un retén inferido. Por lo tanto, no hay ninguna situación en la que el proceso no conduzca esta señal (a menos que se le asigne explícitamente hi-Z).

Actualizar :
La posible solución, como estados, es deshabilitar mutuamente la red activada (ponerla en tri-estado) en dos procesos:
El siguiente código se prueba con Xilinx ISE:

module test_two_drv (select, q);
  input      select;
  output reg     q;

  always @(*)
  begin
    if (select) begin
      q <= 1'b1;
    end else begin
      q <= 1'b0;
    end
  end

  always @(*)
  begin
    if (!select) begin
      q <= 1'b1;
    end else begin
      q <= 1'b0;
    end
  end

endmodule

Es compilar , pero la herramienta síntesis se queja de dos controladores. Al sustituir por el siguiente código:

module test_two_drv (select, q);
  input      select;
  output reg     q;

  always @(*)
  begin
    if (select) begin
      q <= 1'b1;
    end else begin
      q <= 1'bZ;    // <---- Change
    end
  end

  always @(*)
  begin
    if (!select) begin
      q <= 1'b1;
    end else begin
      q <= 1'bZ;   // <---- Change
    end
  end

endmodule

El módulo se sintetiza sin errores y genera el siguiente esquema RTL:

    
respondido por el Eugene Sh.

Lea otras preguntas en las etiquetas