Forum: FPGA, VHDL & Co. multi-cycle aber nicht für einen path sondern ein signal angeben


von Gustl B. (-gb-)


Lesenswert?

Hallo,

ich erzeuge in einer schnellen Taktdomäne ein Signal das sich dort alle 
x Takte verändert wobei x eine feste ganze Zahl ist. Kann man das 
irgendwo als Constraint angeben?
Weil wenn ich dieses Signal in einer langsameren Taktdomäne verwenden 
will müsste ich sonst alle Pfade einzeln constrainen und meiner Meinung 
nach müsste es reichen dem Tool zu sagen wie schnell sich das Signal 
maximal verändert.

Vielleicht noch eine Erklärung wieso ich das gerne so machen würde:
Mein schnelles Signal das sich nur selten ändert heißt data_buffer_1_out 
und das langsame mit dem die Daten dann weiterverarbeitet werden heißt 
data_1. Jetzt probiere ich im VIVADO das Tool um die Constraints zu 
erzeugen, aber das findet eben sehr viele Signale. Ich würde da gerne 
einfach nur zwei Namen eintragen wie sie auch im VHDL stehen. Oder noch 
besser eben der Toolchain mitteilen, dass sich data_buffer_1_out nur 
alle x Takte ändert.

ADC_Port_A/data_buffer_1_out_reg[0]/C 
ADC_Port_A/data_buffer_1_out_reg[0]/CE 
ADC_Port_A/data_buffer_1_out_reg[0]/D
ADC_Port_A/data_buffer_1_out_reg[0]/Q
ADC_Port_A/data_buffer_1_out_reg[0]/R

ADC_Port_A/data_1[0]_i_1/I0 ADC_Port_A/data_1[0]_i_1/I1 
ADC_Port_A/data_1[0]_i_1/I2 ADC_Port_A/data_1[0]_i_1/I3 
ADC_Port_A/data_1[0]_i_1/I4 ADC_Port_A/data_1[0]_i_1/I5 
ADC_Port_A/data_1[0]_i_1/O ADC_Port_A/data_1[0]_i_2/I0 
ADC_Port_A/data_1[0]_i_2/I1 ADC_Port_A/data_1[0]_i_2/I2 
ADC_Port_A/data_1[0]_i_2/I3 ADC_Port_A/data_1[0]_i_2/I4 
ADC_Port_A/data_1[0]_i_2/I5 ADC_Port_A/data_1[0]_i_2/O 
ADC_Port_A/data_1[0]_i_3/I0 ADC_Port_A/data_1[0]_i_3/I1 
ADC_Port_A/data_1[0]_i_3/I2 ADC_Port_A/data_1[0]_i_3/I3 
ADC_Port_A/data_1[0]_i_3/I4 ADC_Port_A/data_1[0]_i_3/I5

Statt Constraints habe ich jetzt mal den xpm_cdc_handshake verbaut. 
Sieht gut aus. Coole Sache ...

: Bearbeitet durch User
von Markus F. (mfro)


Lesenswert?

Gustl B. schrieb:
> ich erzeuge in einer schnellen Taktdomäne ein Signal das sich dort alle
> x Takte verändert wobei x eine feste ganze Zahl ist. Kann man das
> irgendwo als Constraint angeben?
> Weil wenn ich dieses Signal in einer langsameren Taktdomäne verwenden
> will müsste ich sonst alle Pfade einzeln constrainen und meiner Meinung
> nach müsste es reichen dem Tool zu sagen wie schnell sich das Signal
> maximal verändert.

Wenn der schnelle Takt ein phasengleiches ganzzahliges Vielfaches vom 
langsamen ist, kannst Du Multicycles zwischen zwei Takten definieren.

Das gilt dann für alle Taktdomänenübergänge zwischen den beiden Takten. 
Dann mußt Du selbst darauf achten, daß das Signal in der schnellen 
Taktdomäne an der richtigen Stelle der langsamen bereitsteht und lange 
genug aktiv bleibt.

Wenn nicht, ist die Sache sowieso gänzlich asynchron und Du brauchst 
einen FIFO + set_false_path.

von Gustl B. (-gb-)


Lesenswert?

Ok, danke, das werde ich mir mal merken. Habe das jetzt mit 
xpm_cdc_handshake und xpm_cdc_pulse gelöst. Laut Simulation sieht das 
ziemlich fein aus.

von Markus F. (mfro)


Lesenswert?

Gustl B. schrieb:
> Ok, danke, das werde ich mir mal merken. Habe das jetzt mit
> xpm_cdc_handshake und xpm_cdc_pulse gelöst. Laut Simulation sieht das
> ziemlich fein aus.

Ich kenne mich mit Xilinx nicht sonderlich gut aus, aber 
xpm_cdc_handshake scheint für asynchrone CDCs gedacht zu sein. So was 
läßt sich mit Multicycles naturgemäß nicht lösen. Das Macro wird dir 
deshalb wahrscheinlich irgendwo ein set_false_path in die Constraints 
schmuggeln.

Wenn deine Clocks aber synchron sind, ist es definitiv mit Kanonen auf 
Spatzen geschossen. Aber auch nicht schlimm, wenn dich die zusätzliche 
Latenz + Resourcenverbrauch nicht stören.

: Bearbeitet durch User
von Gustl B. (-gb-)


Lesenswert?

So, heute gestestet und funktioniert wunderprächtig. Habe jetzt aber 
eine weitere Frage:

Im FPGA habe ich ein paar Konfigurationsregister angelegt die ich extern 
über UART beschreiben kann. Dazu schicke ich wür oft üblich zuerst die 
Adresse und dann dden Wert. Die Adresse wird dann automatisch um 1 
erhöht und würde ein zweiter Wert kommen geht der eben ins nächste 
Register. Weil da aber Zeiten zwischen den empfangenen Bytes liegen habe 
ich ein Timeout gebaut. Also einen Zähler der bei jedem empfangenen Byte 
wieder auf 0 gesetzt wird. Erreicht der Zähler seinen Höchststand geht 
die Statemachine wieder in den Wartezustand und das nächste empfangene 
Byte ist die neue Startadresse. Nun ist der Zähler lang, also hier habe 
ich den auf etwas über 1 ms eingestellt. Das ist in der Praxis super, in 
der Simulation aber sehr lange. Jetzt würde ich gerne im VHDL etwas 
einbauen damit der in der Simulation und nur dort kürzer ist. Sprich 
sowas wie:

if Simulation = '1' then
signal Reg_Write_Timeout: unsigned(10 downto 0):=(others => '0');
else
signal Reg_Write_Timeout: unsigned(16 downto 0):=(others => '0');
end if;

Gibt es so eine Möglichkeit?

von Samuel C. (neoexacun)


Lesenswert?

Du könntest die Breite des Zählers (oder wie auch immer du seine 
Laufzeit einstellen willst) als vorbelegtes Generic definieren und 
dieses im Falle der Simulation bei der Instanziierung mit einem 
kleineren Wert überschreiben.

von Duke Scarring (Gast)


Lesenswert?

Gustl B. schrieb:
> Gibt es so eine Möglichkeit?
Ja:
1
    function simulation_active return std_ulogic is
2
        variable result : std_ulogic;
3
    begin
4
        result := '0';
5
        -- pragma translate_off
6
        result := '1';
7
        -- pragma translate_on
8
        return result;
9
    end function simulation_active;

Für unterschiedliche Zeiten in Synthese und Simulation nutze ich 
gelegentlich eine Abwandlung davon:
1
    function counter_max return integer is
2
        variable result : integer;
3
    begin
4
        result := 8000000; -- 80 ms
5
        -- pragma translate_off
6
        result := 1600; -- for simulation
7
        -- pragma translate_on
8
        return result;
9
    end function;
10
...
11
   signal counter : integer range 0 to counter_max;

Duke

von Fpga I. (fpga-ing)


Lesenswert?

Duke Scarring schrieb:
> function simulation_active return std_ulogic is
>         variable result : std_ulogic;
>     begin
>         result := '0';
>         -- pragma translate_off
>         result := '1';
>         -- pragma translate_on
>         return result;
>     end function simulation_active;

Die Verwendung von translate_on/off halte ich für ziemlich gefährlich, 
da man so potenziell falsche Werte im aktiven Code einbaut. In vielen 
Branchen ist das "dead code" und darf nicht verwendet werden.
Da empfehle ich wirklich die Verwendung von Generics, die sich für 
einzelne Simulationstestfälle bei Bedarf überschreiben lassen und somit 
auch nicht global für die Verifikation geändert sind.

von Tom (Gast)


Lesenswert?

Fpga I. schrieb:
> Die Verwendung von translate_on/off halte ich für ziemlich gefährlich,
Angsthase :-)

> In vielen Branchen ist das "dead code" und darf nicht verwendet werden.
Welche Branchen wären das z.B.? Und glaubst Du Gustl arbeitet in so 
einer Branche?

> Da empfehle ich wirklich die Verwendung von Generics, die sich für
> einzelne Simulationstestfälle bei Bedarf überschreiben lassen und somit
> auch nicht global für die Verifikation geändert sind.
Geht auch, bei entsprechender Designtiefe muß man entsprechend viele 
Entitys/Components/Packages und Instanzierungen anfassen.

von Fpga I. (fpga-ing)


Lesenswert?

Tom schrieb:
> Welche Branchen wären das z.B.? Und glaubst Du Gustl arbeitet in so
> einer Branche?
z.B. Luftfahrt. Wird hier sicher nicht das Thema sein, aber ein gutes 
coding tut ja auch außerhalb der Branchen häufig seinen zweck

Tom schrieb:
> Geht auch, bei entsprechender Designtiefe muß man entsprechend viele
> Entitys/Components/Packages und Instanzierungen anfassen.

Das Generic muss nicht bis Toplevel hochpropagiert werden, man kann 
entweder ein bestimmtes Generic durch den entsprechenden Pfad ändern 
(der abhängig vom Design länger oder kürzer ist) oder auch alle Generics 
mit genau diesem Namen ändern. Wenn der Name entsprechend eindeutig ist, 
halte ich das auch für einen gut gangbaren weg
(-g vs -G schalter beim vsim)

von C. A. Rotwang (Gast)


Lesenswert?

Tom schrieb:
>> In vielen Branchen ist das "dead code" und darf nicht verwendet werden.
> Welche Branchen wären das z.B.?

Das ist nicht unbedingt Branchenspezifisch, sondern eine Frage der 
gewollten/notwendigen Code-Qualität und damit Sicherheit.

In den Eröterungen zu DO-254 findet sich dazu:
"Dead code can be detrimental when a design is reused and the dead code 
is inadvertently activated during the code base port.
Dead code effects on safety-critical design assurance is not
predictable nor insured to be consistent across different synthesis 
tools, release versions, and even computing environments."

Dazu gibt es auch einen wiki-artikel:
VHDL Code Style und DO-254
Die Ausführung zu toten Code finden sich dort unter SS-17, im Original 
auch zu CP-14.


> Und glaubst Du Gustl arbeitet in so
> einer Branche?

Irrelevant, Qualitätsanspruch ist Charaktereigenschaft.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.