mikrocontroller.net

Forum: FPGA, VHDL & Co. Überlauf / Unterlauf - VHDL


Autor: Mark (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen

Wer kann mir helfen?
Ist wahrscheinlich total trivial für die VHDL-Experten hier...

E(n) = E(n-1) + A - C

Diese Formel gilt es zu implementieren.

C kann die Werte von 8 bis 31 annehmen kann.
A kann 0 bis 511 annehmen.

So, E(n) darf aber nicht kleiner als 0 und darf auch nicht größer als
1023 werden.

Gruss,
Mark

Autor: theFloe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was soll passieren wenn E(n) größer als 1023 bzw kleiner als 0 wäre?
Soll E(n) dann auf 1023 bzw 0 gesetzt werden?

Eine Möglichkeit wäre E(n) per Range bei der Deklaration auf 0 bis 1023
zu beschränken oder:
tmp = E(n-1)+A-C
if tmp >= 1023 then
E(n) = 1023
elsif tmp <= 0 then
E(n) = 0
end if;

Autor: Mark (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Tobias

Ja, danke erst mal.
Aber E(n) soll vom Typ std_logic_vector sein.

Wenn E(n) größer als 1023 oder kleiner 0 wird, so soll E(n) auf 1023
bzw auf 0 begrenzt werden.

Mark

Autor: Ines (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Tobias,

ich habe Dir mal meine Lösung angehängt. Damit wirst Du aber keine
allzuschnelle Systemfrequenz erreichen, da alles in einem Takt
berechnet wird.

Wenn Du Fragen zum Code hast, bitte melden.

Gruß
Ines

Autor: theFloe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Ines,

von Mark kam die Problemstellung :)

Gruß Tobias

Autor: Ines (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh, na gut! Hauptsache Ihr beide verwechselt Euch nicht :-)
Aber danke für den Hinweis!

Autor: FPGA-User (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Ines
Deine Lösung bringt auf Anhieb 3 Errors im Modelsim

@Mark
lass Dir sowas nicht andrehn ;-)))

Autor: Mark (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke, Danke!

Autor: Ines (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@FPGA-User
Der Code war auch mehr als Anregung gedacht. Ich hätte vielleicht
dazuschreiben sollen, dass er weder kompiliert, noch synthetisiert,
noch getestet ist.

@Tobias - arghh - ich meine natürlich Mark :-)))
Ich hoffe, Du kannst trotzdem was damit anfangen!

Autor: Mark (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke Ines!

Autor: FPGA-User (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Mark

um noch nen konstruktiven Beitrag zu leisten, so würde
ich das machen :

   process(reset, clk)

      variable y : signed(11 downto 0); -- Zwischenwert 2 bits mehr

   begin
      if reset = '1' then
         en <= conv_std_logic_vector(0, en'LENGTH);

      elsif rising_edge(clk) then

         y := signed("00" & en) + signed('0' & a) - signed('0' &
c);

         if y > 1023 then
            en <= (others=>'1');
         elsif y < 0 then
            en <= (others=>'0');
         else
            en <= std_logic_vector( y(9 downto 0) );
         end if;


      end if;
   end process;

Es fehlt nur die Zeile, wo en zu Beginn seinen Startwert bekommt.
(Der Code ist simuliert...)

PS : es ist etwas krampfhaft mit std_logic_vector Rechenoperationen
zu machen, besser gehts mit signed, das liest sich dann auch besser

Autor: Mark (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo FGPA-User

Kannst du mir das VHDL-technisch mal erklären, warum es "krampfhaft"
ist, mit std_logic_vector Rechenoperationen zu machen uns warum es
besser mit signed geht?
Danke schon mal.

Ach ja: Danke für deinen Code-Vorschlag!

Was machst du eigentlich hier:
en <= conv_std_logic_vector(0, en'LENGTH);
...und hier:
y  := signed("00" & en) + signed('0' & a) - signed('0' & c);
...und warum eigentlich "signed" und nicht unsigned?

Mark

Autor: FPGA-User (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Mark

en <= conv_std_logic_vector(0, en'LENGTH)

heisst, dass der Wert 0 (den ich als Integer hinschreibe)
auf std_logic_vector konvertiert wird und en zugewiesen
wird. Dabei muss man angeben, wieviele bits en hat (en'LENGTH)
Damit kann ich - wie gesagt - einen Integer an en zuweisen,
fällt mir leichter als binär- oder Hexzahlen im Kopf zu berechnen.
Hier werden keine extra Resourcen benötigt, ich könnte genausogut
schreiben
en <= "0001110011"; -- net ganz so gut lesbar

Die Zeile mit Y ist etwas komplizierter, damit der Vergleich auf
< 0 sauber funktioniert bringe ich alles auf SIGNED.
Dazu müssen alle Summanden (die ja unsigned sind ) um ein MSB
erweitert werden, dass 0 ist. Damit ist klar, dass es positive
Zahlen sind. Ansonsten würde der Compiler das MSB erweitern
und sobald dieses gesetzt wäre (bei a oder c) würde man falsch
rechnen.

Mindestens 1 Summand muss genauso groß sein (Bitbreite) wie das
Ergebnis, deshalb wird en um 2 bits "00" erweitert.
Das war u.a. ein Fehler von Ines.
y ist 2 bits größer als en gewählt, da das Ergebnis nach Deinen
Vorgaben max. 1023 + 511 - 8 = 1526 sein kann, wenn ich mich recht
erinnere 1526. Um +1526 als signed darzustellen braucht man 12 bits
( = -2048 ... + 2047), deshalb ist y 12 bits breit.

Da ich weiss, dass meine Vergleiche y < 0 und y > 1023 abgefangen
haben, kann ich am Ende einfach die 10 LSBs abspeichern.

Hoffe, dass es wenigstens teilweise verständlich ist, hier muss
man mit Binärzahlen und Zahlenformaten einigermaßen sattelfest sein.
Sicher ist es für Anfänger leichter, die Rechnung + Vergleiche
schrittweise zu machen.

Autor: FPGA-User (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Mark

nochwas, std_logic_vector nehme ich eigentlich ungern,
keiner weiß, was die bits darin bedeuten.

Viel besser finde ich:
integer, positive, unsigned, signed, ...

oder sowas:

   type INT_ACK_REG_TYPE is
      record
         int_ack    : INT_SIG_TYPE;
         write_flag : boolean;
      end record;


da weiß man gleich, was dahinter steckt.

Autor: Mark (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo FPGA-User

Sieht elegant aus:
en <= conv_std_logic_vector(0, en'LENGTH)
So werd' ich's in Zukunft auch machen.
;-)

Aber warum du auf SIGNED (also MSB = 1 => Negativ bzw. MSB = 0 =>
Positiv) gehst, verstehe ich immer noch nicht.
(Is' wahrscheinlich ein Verständnis-Problem.)

Nochwas: SIGNED stellt seine Werte doch immer im 2er Komplement dar,
ja?
Also: 111111111 entspricht "Minus-1", ja?

Mark

Autor: FPGA-User (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja, 2er Komplement, die -1 ist richtig

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.