Forum: FPGA, VHDL & Co. GHDL: multiple assignments


von HwTest (Gast)


Lesenswert?

Hallo,

ich bin gerade dabei eine Testbench aufzusetzen und auszuprobieren, GHDL 
meldet einen bound check failure an der markierten Stelle im Code. Es 
passiert bei der Inkrementierung von rxDataCounter. Ich verstehe nur 
nicht warum, denn ich habe einen bound check direkt darunter eingefügt, 
er wird nur nicht beachtet. Bisher war mein Verständnis, dass bei 
mehreren Zuweisungen der letzte gewinnt, ich dachte ich spar mir einfach 
den else-Zweig. GHDL scheint aber die Inkrementierung direkt 
auszuführen. Habe ich da was falsch verstanden, macht GHDL hier etwas 
falsch oder muss der Fehler wo anders liegen?
1
if uartRxEmpty = '0' then
2
   -- byte received, save data
3
   rxMemory(rxDataCounter) <= uartRxData;
4
   rxDataCounter <= rxDataCounter + 1; -- <- bound check failure
5
   dataReceived <= true;
6
7
-- if last data, next state
8
   if rxDataCounter = DATA_LENGTH-1 then -- <- check
9
      rxDataCounter <= 0; -- <- zweite Zuweisung
10
      dataReceived <= false;
11
12
       state <= STATE_EXEC;
13
   end if;
14
--...

Vielen Dank!

von Donni D. (Gast)


Lesenswert?

Überprüf das mit dem length - 1 mal dadrüber und erhöhe in nem else. 
Vielleicht hilft das.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

HwTest schrieb:
> Es passiert bei der Inkrementierung von rxDataCounter. Ich verstehe nur
> nicht warum, denn ich habe einen bound check direkt darunter eingefügt,
> er wird nur nicht beachtet.
Weil die Grenze schon vor deinem Check verletzt wird?
Wenn der rxDataCounter z.B. als Integer mit einem Range angegeben ist, 
dann prüft der Simulator bei jeder Änderung seines Wertes, ob dieser 
Bereich verletzt wird.

BTW: du programmierst hier keine Software. Auch wenn es so aussieht...

: Bearbeitet durch Moderator
von HwTest (Gast)


Lesenswert?

Ja mit einem else-Zweig gehts. Aber müsste es nicht auch ohne gehen?

Sind beide VHDL Codestücke nicht equivalent, wenn a = n? a wird der Wert 
1 zugewiesen.
1
a <= 0; -- wird ignoriert
2
a <= 1;
1
a <= 0; -- wird ignoriert?
2
if a = n then
3
  a <= 1;
4
end if;

Lothar M. schrieb:
> Wenn der rxDataCounter z.B. als Integer mit einem Range angegeben ist,
> dann prüft der Simulator bei jeder Änderung seines Wertes, ob dieser
> Bereich verletzt wird.

Ok, verständlich, aber rxDataCounter wird nie größer als DATA_LENGTH-1, 
wenn das Signal nur an dieser einen Stelle verändert wird, oder?

von berndl (Gast)


Lesenswert?

HwTest schrieb:
> Ja mit einem else-Zweig gehts. Aber müsste es nicht auch ohne gehen?

Nein. Deine Zeile
   rxDataCounter <= rxDataCounter + 1; -- <- bound check failure
wird vom Simulator dahingehend interpretiert, dass du ueber den 
definierten Range hinaus inkrementierst. Deshalb der "bound check".
Wenn du das so machen willst, dann muss dein definierter Range des 
Integers eben eins groesser sein...
Oder den Zaehler halt als "unsigned" bauen, da gibt's evtl. einen 
Ueberlauf, der allerdings nie zum tragen kommt.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

HwTest schrieb:
> a <= 0; -- wird ignoriert
Das wird nicht ignoriert, sondern hier
> a <= 1;
erhält a einen "aktuelleren" Wert, den a am Prozessende übernimmt.

HwTest schrieb:
> Ok, verständlich, aber rxDataCounter wird nie größer als DATA_LENGTH-1,
> wenn das Signal nur an dieser einen Stelle verändert wird, oder?
Doch, es wird an dieser Stelle genau DATA_LENGTH groß:
rxDataCounter <= rxDataCounter + 1;
Denn einen Zyklus vorher war es ja noch DATA_LENGTH-1 groß:
1
if uartRxEmpty = '0' then
2
   -- byte received, save data
3
   rxMemory(rxDataCounter) <= uartRxData;
4
   rxDataCounter <= rxDataCounter + 1;     --  hier wird ein neuer Wert für rxDataCounter  berechnet aber NICHT zugewiesen 
5
   dataReceived <= true;
6
7
-- if last data, next state
8
   if rxDataCounter = DATA_LENGTH-1 then   -- hier wird der nicht inkrementierte Wert von rxDataCounter  zum Vergleich verwendet
9
      rxDataCounter <= 0; -- <- zweite Zuweisung
10
      dataReceived <= false;
11
12
       state <= STATE_EXEC;
13
   end if;
14
15
end process;                              -- hier erhält rxDataCounter den oben inkrementierten Wert
Kurz: in einem Prozess "gewinnt" die letzte Zuweisung (vor einem 
Prozessende oder wait) an ein Signal. Bis zu dieser Zuweisung "behält" 
das Signal seinen Wert.

von HwTest (Gast)


Lesenswert?

Vielen Dank, nach der Ausführung hab ichs nun verstanden. Die Testbench 
tut jetzt auch wie gedacht. In Zukunft werde ich nicht an einer 
zusätzlichen Verzweigung sparen (sowie besser für die Lesbarkeit). Den 
Wertebereich könnte ich natürlich auch anpassen, aber die andere 
Variante ist wohl sauberer. :)

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.