Überlauf / Unterlauf - VHDL

Gast #252256
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
Gast #252257
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:
1
tmp = E(n-1)+A-C
2
if tmp >= 1023 then
3
E(n) = 1023
4
elsif tmp <= 0 then
5
E(n) = 0
6
end if;
Gast #252264
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!
Gast #252266
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
Gast #252267
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
Gast #252268
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.
Gast #252269
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.
Gast #252270
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren