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:
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
@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