Servus,
ich habe mir einen Zähler gemacht mit 30 Bit Breite, der außer dem
reinen Zählen noch folgende Funktionen hat:
- enable-Signal
- updown ('1' = up)
- clr (alles auf 0 setzen)
- maximale Adresse, bis zu der der Counter läuft, 30 Bit
- Schrittweite, 20 Bit maximal
Aber jetzt habe ich das Problem, dass mir die Zeit beim gewünschten Takt
bei der Synthetisierung bei weitem nicht reicht (ca. 15 ns statt 10 ns).
Ich habe jetzt auch ca. 1 Jahr kein VHDL mehr gemacht und bin da noch
nicht 100%-ig drin.
Wenn jemand Optimierungspotenzial sieht, wäre das super!
Gruß
Jonas
1
LIBRARYIEEE;
2
USEIEEE.STD_LOGIC_1164.ALL;
3
USEIEEE.NUMERIC_STD.ALL;
4
5
6
ENTITYCNTIS
7
PORT
8
(
9
clock:INSTD_LOGIC;
10
reset:INSTD_LOGIC;
11
cnt_en:INSTD_LOGIC;
12
clr:INSTD_LOGIC;
13
updown:INSTD_LOGIC;
14
max_adr:INSTD_LOGIC_VECTOR(29DOWNTO0);
15
step:INstd_logic_vector(19DOWNTO0);
16
q:OUTSTD_LOGIC_VECTOR(29DOWNTO0)
17
);
18
ENDCNT;
19
20
21
ARCHITECTURErtlOFCNTIS
22
23
signalcount:unsigned(29DOWNTO0);
24
signalmax:unsigned(29DOWNTO0);
25
signalstp:unsigned(29DOWNTO0);
26
27
BEGIN
28
q<=std_logic_vector(count);
29
max<=unsigned(max_adr);
30
stp<=unsigned("0000000000"&step);
31
32
counting:PROCESS(reset,clock)
33
BEGIN
34
IF(reset='1')THEN
35
count<=(others=>'0');
36
ELSIF(rising_edge(clock))THEN
37
IF(clr='1')THEN
38
count<=(others=>'0');-- bei clr auf 0 setzen
39
ELSE
40
IF(cnt_en='1')THEN-- enable-Signal
41
IF(updown='1')THEN-- up
42
IF(((count-1)>=(max-stp))and(count/=0))THEN--???
43
count<=(max-count-1)+stp;
44
ELSE
45
count<=count+stp;-- hochzählen
46
ENDIF;
47
ELSE-- down
48
IF(count<stp)THEN--???
49
count<=(max-stp)+count+1;
50
ELSE
51
count<=count-stp;-- runterzählen
52
ENDIF;
53
ENDIF;
54
ENDIF;
55
ENDIF;
56
ENDIF;
57
ENDPROCESS;
58
59
ENDrtl;
Am schlechtesten erscheinen mir die beiden Bedingungen, die ich mit ???
markiert habe, wegen der Rechnerei und und dem größer/kleiner. Mir ist
aber keine bessere Lösung eingefallen.
Horn schrieb:> Schon alle Fälle simuliert?>> Was sagt die Synthese? Wieviel Megaherzen schaffst du?
Bei Simulieren bin ich gerade.
Zum Takt hab ich oben die Zeiten geschrieben: 100MHz will ich (10ns).
Schaffen tu ich derzeit um die 15ns, sagt die Synthese
Das ganz auf einem Cyclone II mit Speed Grade -8.
Später soll das mal auf einen Cyclone V mit bessserem Speed grade, geht
aber halt jetzt noch nicht mangels Hardware.
Eventuell sieht ja jemand etwas, was extrem schlecht und langsam ist. Es
kommt ja oft auc himmer auf die Schreibweise an.
Ich wüsste eben, dass größer/kleiner deutlich schlechter ist als =, aber
ich seh keinen Weg, das zu vermeiden....
Muss der Zähler strikt binär zählen, oder reicht dir evtl. eine andere
Ordnung? Eine Alternative kann ein LFSR mit entsprechender Periodenlänge
sein.
Das macht jedoch nur dann Sinn, wenn die Umwandlung zwischen LFSR und
Periodenindex in Binärzählform nicht so häufig vorkommt, dass du den
Geschwindigkeitsvorteil wieder verlierst.
Der Geschwindigkeitsvorteil des LFSR kommt dadurch, dass es keine
Situation gibt in der ein Zählschritt durch den gesamten Vektor
propagiert.
Beispielsweise praktisch bei Speicherort-Zählern in LAs und co, wo der
reale Speicherort egal ist solange die Ordnung erhalten bleibt.
Maxx schrieb:> Der Geschwindigkeitsvorteil des LFSR kommt dadurch, dass es keine> Situation gibt in der ein Zählschritt durch den gesamten Vektor> propagiert.
Jonas zählt ja nicht in Schritten von 1 hoch sondern in einstellbarer
Schrittweite von 1 bis 2^29-1. Da hilft ihm imho auch eine andere
Codierung des Zählers nichts, und da lässt sich auch ein Vergleich mit
"größer/kleiner" statt nur mit "gleich" kaum vermeiden.
Wenn dein FPGA DSP-Kerne hat, dann können diese die Addition und den
Vergleich vielleicht schneller durchführen als die Logik in LUTs. (der
Vergleich "kleiner als" lässt sich als Subtraktion mit anschließendem
Vorzeichencheck bauen). Bin aber nicht sicher, ob du es damit wirklich
schneller hinkriegst...
Achim S. schrieb:> Wenn dein FPGA DSP-Kerne hat, dann können diese die Addition und den> Vergleich vielleicht schneller durchführen als die Logik in LUTs. (der> Vergleich "kleiner als" lässt sich als Subtraktion mit anschließendem> Vorzeichencheck bauen). Bin aber nicht sicher, ob du es damit wirklich> schneller hinkriegst...
Das werd ich morgen mal ausprobieren!
Maxx schrieb:> Muss der Zähler strikt binär zählen, oder reicht dir evtl. eine andere> Ordnung? Eine Alternative kann ein LFSR mit entsprechender Periodenlänge> sein.
wie bereits gesagt, einstellbare Schrittweite zwischen 1 und ...
Was mir jetzt noch am ehesten eingefallen ist, wäre "manuelles
Pipelining". Nämlich, dass ich die IF-Bedingung
1
IF(((count-1)>=(max-stp))and(count/=0))THEN
in mehrere Schritte aufteile: erst das arithmische (also max-stp), dann
der Vergleich, gespeichert in einem Signal, und damit im 3. Takt in das
if und neue count-Zuweisung (also bspw. 3 Takte statt in einem).
Damit müsste es schneller zu schaffen sein.
Ich werde morgen mal die beiden Möglichkeiten austesten und dann
hoffentlich zu einer Lösung kommen...
Jonas K. schrieb:> in mehrere Schritte aufteile: erst das arithmische (also max-stp), dann> der Vergleich, gespeichert in einem Signal, und damit im 3. Takt in das> if und neue count-Zuweisung (also bspw. 3 Takte statt in einem).>> Damit müsste es schneller zu schaffen sein.
richtig, so schaffst du voraussichtich einen schnelleren Takt. Dafür
brauchst du dann aber mehrere Takte für einen Zählschritt, das
eigentliche Zählen wird also eher langsamer.
Im Prinzip könntest du auch so pipelinen, dass der Zähler pro Takt um
eins hochzählt. Dann müsstest du aber gehörig um die Ecke denken: also
nicht vergleichen, ob der Zähler im nächsten Schritt über die Grenze
läuft, sondern vergleichen ob der Zähler im überübernächsten Schritt
über die Grenze läuft.
>> IF(count < stp) THEN --???>> count <= ( max - stp ) + count + 1;
Der Pfad ist extrem lang.
Du hast aber wenig Chancen, weil sowohl deine Zählschritte als auch die
obere Grenze voll variabel sind und du deshalb nicht im Voraus rechnen
kannst, das Ergebnis aber schon 1 Takt später brauchst.
Wenn du diese Beiden zum Generic machst bekommst du das Modul
warscheinlich locker auf 200 MHz, auch im Cyclone 2.
Hallo
ich halte die Schachtelung der if-statements für kontraproduktiv
die zählschleife sollte so kurz wie möglich sein
für die Bereichskontrolle verwende flags
zurücksetzen, parameter ändern etc gehört gar nicht in die Schleife
sondern sollte eine externe funktion
Das alles bläht nur die main loop und kostet dich zeit welche dir zum
zählen fehlt.
bin kein VHDL Freak aber selbst in C sähe das bei mir nicht so aus
statt der ersten 3 If-Statements würde ich eine Logische Veknüpfung
wählen
so das der clock eingefrohren wird solange reset, clr anliegen oder
cnt-enable nicht freigegeben sind .....
sorry
MFG Winne
Das ist richtig. Die Schrittweite liesse sich durch die geeignete wahl
des Polynoms variieren, jedoch ist der < / > Vergleich in der Ordnung
aufwendig.
Es braucht aber keine volle Substraktion bei dem Urspünglichen Konzept.
(Du willst ja nicht wissen wieviel, sondern nur ob der eine Wert größer
ist. Das lässt sich auch durch andere Art testen.
z.B. in dem man das höchstwertigste abweichende Bit testet. ist dies im
Substrahenden gesetzt, so ist dieser Größer.
wenn A xor B = 0 -> A == B
sonst wenn (B and HighestBitValue(A xor B)) -> A < B
HighestBitValue kann in einer Baumstruktur aufgebaut werden und hat
einen zu der Bitbreite logarithmische Pfadlänge. Addition/Substraktion
durch das Carry eine Lineare.
Bei 30 Bit würde ich das als alternativen Vergleich mal testen.
Ev., wenn deine Anwendung es hergibt, nicht den Maximalen counterwert
einstellbar machen, sondern anstelle von 30bit 31bit verwenden, und wenn
das MSB darin 1 ist, ist der Zähler voll und Zählt nicht weiter, mittels
Zählinterval kann man dann die maximale Anzahl von Schritten einstellen.
VHDL++ schrieb im Beitrag #3403391:
>>> IF(count < stp) THEN --???>>> count <= ( max - stp ) + count + 1;>> Der Pfad ist extrem lang.>> Du hast aber wenig Chancen, weil sowohl deine Zählschritte als auch die> obere Grenze voll variabel sind und du deshalb nicht im Voraus rechnen> kannst, das Ergebnis aber schon 1 Takt später brauchst.>> Wenn du diese Beiden zum Generic machst bekommst du das Modul> warscheinlich locker auf 200 MHz, auch im Cyclone 2.
Im Voraus rechnen kann ich schön, dann sieht halt die Bedingung anders
aus, und die Einstellungen max und step haben einen Takt Verzögerung.
Wenn ich die beiden Eingangsgrößen als Generic mache, kann ich das ganze
ja nicht zur Laufzeit umkonfigurieren. Das ist irgendwie unpassend.
Winfried J. schrieb:> bin kein VHDL Freak aber selbst in C sähe das bei mir nicht so aus>> statt der ersten 3 If-Statements würde ich eine Logische Veknüpfung> wählen
Da hast du wohl noch nicht viel mit VHDL zu tun gehabt ;) Alles was du
siehst, geschieht in einem Takt! Und solche If's, auch verschachtelt -
werden theoretisch von der Synthese-Software optimiert. Also IF(x1 and
X2 and X3) ist identisch mit IF(X1) IF(X2) IF (X3)
Maxx schrieb:> wenn A xor B = 0 -> A == B> sonst wenn (B and HighestBitValue(A xor B)) -> A < B>> HighestBitValue kann in einer Baumstruktur aufgebaut werden und hat> einen zu der Bitbreite logarithmische Pfadlänge. Addition/Substraktion> durch das Carry eine Lineare.
Sehr gut, Merce :)
bko schrieb:> zusätzlich könnte auch ein Synchroner Reset helfen.> ..............> .............> neu:> signal count : unsigned (29 DOWNTO 0) := "0000"; //syntax evtl falsch!> (...)> IF(rising_edge(clock)) THEN> IF(clr='1') THEN> count <= (others => '0'); -- bei clr auf 0 setzen>> Beitrag "Re: Xilinx und die Resets"
Interessant, ist mir neu. Einen Reset werde ich überhaupt brauchen,
inwiefern das alle Teile betrifft oder nur manche, ist aber zu
überlegen, wenn Altera das genauso wie Xilinx macht. Werd ich mal
nachlesen!
Achim S. schrieb:> Im Prinzip könntest du auch so pipelinen, dass der Zähler pro Takt um> eins hochzählt. Dann müsstest du aber gehörig um die Ecke denken: also> nicht vergleichen, ob der Zähler im nächsten Schritt über die Grenze> läuft, sondern vergleichen ob der Zähler im überübernächsten Schritt> über die Grenze läuft.
So wars gemeint :)
wohl zu kompliziert ausgedrückt^^
chris schrieb:> Ev., wenn deine Anwendung es hergibt, nicht den Maximalen counterwert> einstellbar machen, sondern anstelle von 30bit 31bit verwenden, und wenn> das MSB darin 1 ist, ist der Zähler voll und Zählt nicht weiter, mittels> Zählinterval kann man dann die maximale Anzahl von Schritten einstellen.
Das funktioniert so nicht, da der Zählerstand ja z. B. eine Adresse im
RAM/LUT repräsentiert und deswegen SOWOHL die maximale Adresse (Anzahl
aktuell gespeicherter Werte) ALS AUCH die Schrittweite
(Frequenzveränderung) anpassbar sein soll.
Und Danke mal für all eure Antworten, ist wirklich sehr aufschlussreich
:)
So, jetzt hab ich die Erkennung größer / kleiner gepipelinet. Damit bin
ich von 15 ns auf 10.012 ns Laufzeit gekommen. (benötigt für 100MHz sind
ja 10 ns)
Also so gut wie geschafft, mit dem anderen Algorithmus zur Vergleich
sollte das ganze ja noch mal besser werden...
Schon beim reset sehe ich optimierungspotential:
Brauchst du einen asynchronen Reset? Falls nein, dann forme ihn in einen
synchronen um. Zumindest bei Xilinx bringt das vorteile, weil der
FF-Reset entweder synchron oder asynchron sein kann, ist es asynchron
stehen die RS Eingange nicht mehr zur Verfügung und müssen über Logik
vor dem D- Eingang des FF nachgebildet werden.
Wenn du nur einen PowerUp reset benötigst, dann den resetzweig komplett
rausnehmen. Signale werden bei der Konfiguration schon initialisiert, da
brauchst keine extra Initialisierungsschaltung.
Extra reset für flag scheint mir auch unnötig. Flag wird vom counter
abgeleitet, wird dieser gereset edann hat das auch einfluß auf das Flag.
MfG,
Leonard Lebewohl schrieb:> Schon beim reset sehe ich optimierungspotential:>>> Brauchst du einen asynchronen Reset?
Ist bei Altera allerdings anders als bei Xilinx, die haben einen
asynchronen reset integriert, und dann kann ich den ja auch verwenden.
Mit dem Pipelining habe ich die Verzögerung des Vergleichs und des
Addierens+Subtrahierens vor den eigentlichen Zähler auf unter 8ns
(gefordert 10) gebracht.
Am längsten braucht jetzt noch folgender Teil - nämlich der eigentliche
Zähler:
Wenn Deine Anwendung es erlaubt, hilft's ja vielleicht, den Counter zu
splitten, also einen Up- und einen Down-Counter parallel zu bauen. Das
updown-Signal steuert dann einen Muxer, der den gewünschten Counter
auswählt. Das geht natürlich nur, wenn der Counter nicht hin und
herzählen soll...
Jonas K. schrieb:> ENTITY CNT IS> PORT> (> clock : IN STD_LOGIC ;> reset : IN STD_LOGIC ;> cnt_en : IN STD_LOGIC ;> clr : IN STD_LOGIC ;> updown : IN STD_LOGIC ;> max_adr : IN STD_LOGIC_VECTOR (29 DOWNTO 0);> step : IN std_logic_vector (19 DOWNTO 0);> q : OUT STD_LOGIC_VECTOR (29 DOWNTO 0)> );> END CNT;
Das Updown kann man sich sparen wenn man fürs decrement step mit dem
Zweikomplement der stepsize lädt,
x-a = x + (-a)
Dann braucht es keinen Muxer, allerdings muss step auf 30 bit erweitert
werden.
MfG,
Fpga Kuechle schrieb:> Jonas K. schrieb:>> ENTITY CNT IS>> PORT>> (>> clock : IN STD_LOGIC ;>> reset : IN STD_LOGIC ;>> cnt_en : IN STD_LOGIC ;>> clr : IN STD_LOGIC ;>> updown : IN STD_LOGIC ;>> max_adr : IN STD_LOGIC_VECTOR (29 DOWNTO 0);>> step : IN std_logic_vector (19 DOWNTO 0);>> q : OUT STD_LOGIC_VECTOR (29 DOWNTO 0)>> );>> END CNT;>>> Das Updown kann man sich sparen wenn man fürs decrement step mit dem> Zweikomplement der stepsize lädt,>> x-a = x + (-a)>> Dann braucht es keinen Muxer, allerdings muss step auf 30 bit erweitert> werden.>> MfG,
mag sein, dass ich dann denselben addier/subtrahier-Vorgang habe. Der
Überlauf ist aber flexibel, dafür brauche ich doch noch zwei
Bedingungen, oder?
Überlauf mit positivem Step
1
count<=(max-count-1)+stp;
2
-- up ^ down v
3
count<=(max-stp)+count+1;
Änderung bei updown-abhängigem Vorzeichen von Step (immer + vor step)
1
count<=(max-count-1)+stp;
2
-- up ^ down v
3
count<=(max+stp)+count+1;
Der verbleibende Unterschied ist also noch die +/- 1!
Am besten man zeichnet ein kleines Blockbild (siehe Anhang).
Fürt den vergleich ob die Grenze des Adressbereichs erreicht ist führt
man ein register ein, das fur up und down jeweils mit der ersten
unzulässigen Adresse vor addition des stepsize geladen wird (up:MAX -
step + 1; down: Min+step - 1). Ist die Grenze überschritten wird die
berechnete Adresse nicht in das Ausgangregister geladen. Step ist für
downwards negativ (zweikomplemant) Das Richtungsbit für den
Bereichscomperator kann man sich sparen wenn man ein höherwertiges bit
(z.b (29) von step nimmt. Für negatives step sind diese ja '1'. Dann
dreht sich allerdings die Polarität um. Den Code habe ich ohne reset
geschrieben, für asynchronen reset die auskommentierten Zeilen
verwenden.
MfG:
Fpga Kuechle schrieb:> Am besten man zeichnet ein kleines Blockbild (siehe Anhang).>> Fürt den vergleich ob die Grenze des Adressbereichs erreicht ist führt> man ein register ein, das fur up und down jeweils mit der ersten> unzulässigen Adresse vor addition des stepsize geladen wird (up:MAX -> step + 1; down: Min+step - 1). Ist die Grenze überschritten wird die> berechnete Adresse nicht in das Ausgangregister geladen. Step ist für> downwards negativ (zweikomplemant) Das Richtungsbit für den> Bereichscomperator kann man sich sparen wenn man ein höherwertiges bit> (z.b (29) von step nimmt. Für negatives step sind diese ja '1'. Dann> dreht sich allerdings die Polarität um. Den Code habe ich ohne reset> geschrieben, für asynchronen reset die auskommentierten Zeilen> verwenden.>> MfG:
Ich hatte jetzt mal deinen Code übernommen und noch weiter angepasst
(dass beim Überlauf wieder der entgegesnette Wert geladen wird und das
mit dem negativen Step). Dann hab ich allerdings wieder das alte
Problem, dass ich noch pipelinen müsste....
Deswegen hab ich doch den Code genommen, den ich bis Freitag fabriziert
hatte... Da ist das Pipelining der Additionen und der Vergleiche bereits
gemacht.
Deswegen schaut der Code jetzt so aus:
1
LIBRARYIEEE;
2
USEIEEE.STD_LOGIC_1164.ALL;
3
USEIEEE.NUMERIC_STD.ALL;
4
5
6
ENTITYCNTIS
7
PORT
8
(
9
clock:INSTD_LOGIC;
10
reset:INSTD_LOGIC;
11
cnt_en:INSTD_LOGIC;
12
clr:INSTD_LOGIC;
13
updown:INSTD_LOGIC;
14
max_adr:INSTD_LOGIC_VECTOR(29DOWNTO0);
15
step:INstd_logic_vector(19DOWNTO0);
16
q:OUTSTD_LOGIC_VECTOR(29DOWNTO0)
17
);
18
ENDCNT;
19
20
21
ARCHITECTURErtlOFCNTIS
22
23
signalcount:unsigned(29DOWNTO0);
24
signalmax:unsigned(29DOWNTO0);
25
signalstp:unsigned(29DOWNTO0);
26
signaltwostp:unsigned(29DOWNTO0);
27
signalcmp:unsigned(29DOWNTO0);
28
signaltmp:unsigned(29DOWNTO0);
29
signaltmp_pre:unsigned(29DOWNTO0);
30
signalflag:boolean;
31
signalflag_delayed:boolean;
32
signalupdown_delayed:std_logic;
33
34
BEGIN
35
q<=std_logic_vector(count);
36
max<=unsigned(max_adr);
37
stp<=unsigned("0000000000"&step);
38
39
40
41
counting:PROCESS(reset,clock)
42
BEGIN
43
IF(reset='1')THEN
44
count<=(others=>'0');
45
cmp<=(others=>'0');
46
tmp<=(others=>'0');
47
tmp_pre<=(others=>'0');
48
twostp<=(others=>'0');
49
ELSIF(rising_edge(clock))THEN
50
-- make stp+step, as it's needed often in cmp
51
twostp<=stp+stp;
52
-- make cmp for camparing with count and tmp for faster adding ...
53
IF(updown='1')THEN
54
cmp<=(max-twostp);
55
tmp<=(max+tmp_pre);-- max -1 +stp
56
tmp_pre<=(stp-1);
57
ELSE
58
cmp<=twostp;
59
tmp<=(max-tmp_pre);-- max +1 -stp
60
tmp_pre<=(stp-1);
61
ENDIF;
62
-- delay updown, to see if it's changed
63
updown_delayed<=updown;
64
65
IF(clr='1'or(updown/=updown_delayed))THEN-- just a clear-signal
66
IF(updown='0')THEN
67
flag<=false;
68
count<=max-stp;
69
ELSE
70
count<=stp;
71
flag<=false;
72
ENDIF;
73
ELSE-- set flag, comparing count with comp...
74
-- Optimierungsmöglichkeit: </> ersetzen durch Baumstruktur mit nlogn statt n²
75
IF(updown='1')THEN
76
flag<=((count>(cmp)));
77
flag_delayed<=notflag;
78
ELSE
79
flag<=(((count)<cmp));
80
flag_delayed<=notflag;
81
ENDIF;
82
83
IF(cnt_en='1')THEN
84
IF(updown='1')THEN
85
-- count+step element [max-stp+1;max] => neuer bereich
86
-- count element [max-step-step+1;max-step]
87
-- falls größer als max-step -> auch auf 0 setzen (verzählt? max-Änderung?)
88
-- also muss count größer sein als max -stp -stp +1 -> cmp-Berechnung außerhalb
89
IF(flagandflag_delayed)THEN
90
-- count element [max;max-stp+1]
91
-- IF(((count-1) >= (max-stp)) and (count /= 0)) THEN
92
count<=(tmp)-count;
93
ELSE
94
count<=count+stp;
95
ENDIF;
96
ELSE
97
-- count+step element [0;stp-1] => neuer bereich
98
-- count element [stp;step+step-1]
99
-- falls kleiner als step -> auch flag setzen (verzählt? max-Änderung?)
100
-- also muss count kleiner sein als stp+stp-1 -> cmp-Berechnung außerhalb
Jonas K. schrieb:> Fpga Kuechle schrieb:
Hallo Jonas,
meines Erachtens stösst schneller zum Kern des timingproblems wenn man
sich vom VHDL-Code löst und die Schaltung im Blockbild analysiert. Hat
man dann einen neue Lösung gefunden schreibt man diese in VHDL/Code und
synthetisiert zur Probe. Optimierungsmethoden wie in C (loop unrolling,
Schachteltiefe begrenzen, Makros (inlinecode) verwenden greifen hier
nicht.
Meines erachtens ist es auch übersichlicher nur die Speicherung des
Zählerstandes in den Prozess zu schreiben und die ganze Kombinatorik
inklusive des kritischen Pfades ausserhalb.
1
IF(updown='1')THEN
2
flag<=((count>(cmp)));
3
flag_delayed<=notflag;
4
ELSE
5
flag<=(((count)<cmp));
6
flag_delayed<=notflag;
7
ENDIF;
ich vermisse den Fall count = tmp. Da flag_deöayed identisch zugewiesen
wird, sollte man es über das erste IF ziehen, ist übersichtlicher.
1
count<=max-stp;
da max und stp letzlich eingangsport sind, ändert sich max-step nicht
während der Berechnung. Falls du siese differenz wirklich benötigst,
dann kann man sie ebenso als eingangsport definieren und wie ein
normales steuerregister beschreiben. das spart den subtractor. ebenso
twostp. wobei letzteres durch ein linksshift ersetzbar ist:
1
twostp<=stp+stp;
2
-- step(28 downto 1) & '0' --ist dasselbe ohne adder
Folgendes verstehe ich nicht, clear soll doch alles auf Null setzen?
Wahrscheinlich meinst du "load" laden eines Register/Zählers mit einem
eingangsparameter.
1
IF(clr='1'or(updown/=updown_delayed))THEN-- just a clear-signal
2
IF(updown='0')THEN
3
flag<=false;
4
count<=max-stp;
5
ELSE
6
count<=stp;
7
flag<=false;
8
ENDIF;
wie gesagt, meines Erachtens erst Blockbild skizieren, dann in VHDL
umsetzen.
MfG,