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
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; |
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
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
Oh, na gut! Hauptsache Ihr beide verwechselt Euch nicht :-) Aber danke für den Hinweis!
@Ines Deine Lösung bringt auf Anhieb 3 Errors im Modelsim @Mark lass Dir sowas nicht andrehn ;-)))
@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!
@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
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
@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.
@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.
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.