Gibt es eine Möglichkeit, einen Kompilierzeitfehler in Verilog bedingt auszulösen?

Ich habe ein parametrisiertes Modul in Verilog, bei dem die Parameter eine Taktrate und eine Aktualisierungsrate sind, die verwendet werden, um zu berechnen, wie viele Inaktivitätszyklen zwischen Instanzen einer sich wiederholenden Operation eingefügt werden. Es ist jedoch sehr einfach, Parameter einzustellen, die nicht erreicht werden können (da die Operation eine nicht triviale Zeitdauer in Anspruch nimmt, sodass die Wiederholung erfolgen müsste, bevor sie abgeschlossen ist), und im Moment gibt das Design keine Rückmeldung darauf.

Ich habe mich gefragt, ob es eine Möglichkeit gibt, während der Synthese (oder Kompilierung vor der Simulation) einen Fehler auszulösen, wenn die Bedingungen nicht erfüllt werden können (dh wenn ein lokaler Parameter kleiner als ein anderer ist)? Vielleicht ein Äquivalent zum beliebten C/C++-Compile-Time-Assert-Hack.

Antworten (3)

Ich bin mir sicher, dass es eine Möglichkeit gibt, einen C/C++-Rückruf zur Kompilierzeit einzubinden. Solange Ihre generateBlöcke jedoch unterstützt werden (eingeführt in IEEE Std 1364-2001), können Sie Folgendes tun:

generate
if (CONDITION > MAX_ALLOWED /* your condition check */ ) begin
    illegal_parameter_condition_triggered_will_instantiate_an non_existing_module();
end
endgenerate

Wenn die Bedingung wahr ist, gibt der Compiler einen Fehler aus, da eine Anfrage für etwas vorliegt, das nicht existiert. Wenn die Bedingung falsch ist, wird die Operation übersprungen. Die einzige Anforderung ist, dass der Code für die illegale Bedingung der legalen Verilog-Syntax folgt und die illegale Bedingung niemals versehentlich gültig wird (daher der lange und ausführliche nicht existierende Modulname).

Wenn Ihre Simulator- und Synthesetools IEEE Std 1800-2009 (SystemVerilog-Revision, veröffentlicht 2009) oder eine neuere Revision unterstützen, können Sie $error()den Fehler verwenden und eine aussagekräftigere Meldung angeben. Ich bin mir nicht sicher, ob ein Anbieter diese Funktion bereits implementiert hat. Es sollte die bevorzugte Methode werden, sobald die meisten Anbieter implementiert sind, daher werde ich ein Beispiel geben:

generate
if (CONDITION > MAX_ALLOWED /* your condition check */ ) begin
    $error("%m ** Illegal Condition ** CONDITION(%d) > MAX_ALLOWED(%d)", CONDITION, MAX_ALLOWED);
end
endgenerate

Du könntest so etwas machen:

module test();

  parameter VALUE=16;

  // VALUE should be between 16 and 64
  wire [64:16] range_for_value;
  assign range_for_value[VALUE] = 1'b0;

endmodule

Tools behandeln dies möglicherweise etwas anders, aber wenn VALUEes nicht im erwarteten Bereich liegt, sollte es wirklich ein Fehler sein, da der Bitindex für die Assign-Anweisung außerhalb der Grenzen von liegt range_for_value.

Stimmt es wirklich, dass es in Verilog so etwas wie „assert“ nicht gibt? Das ist ziemlich grundlegendes Zeug!

Wenn Ihre Tools gemischte Sprachen unterstützen, können Sie ein Modul hinzufügen, das nur eine VHDL-Entität mit den erforderlichen Ports oder Generika und der offensichtlichen ASSERT-Anweisung ist. Bei Kompilierungs- oder Ausarbeitungszeit bestimmbaren Bedingungen funktioniert dies in Sim oder Synthese (zumindest mit XST oder Synplicity) gleichermaßen gut.

entity CheckSize is
   generic (depth : natural := 16);
   port (data : std_logic_vector);
end CheckSize;

architecture empty of CheckSize is
begin
   Assert depth * data'length <= 256 Report "Size too large!" 
      severity Failure;
end empty;

Keine der bisherigen Antworten ist wirklich zufriedenstellend, außer vielleicht die "System Verilog 2009" $error(), aber dies ist wahrscheinlich die einfachste für die breiteste Palette von Tools.