Hallo!
Ich probiere gerade mal etwas mit Schieberegistern rum und habe das
Problem, dass ich es nicht schaffe ein Bit mitten im SR zu verändern.
Diesen Code habe ich von der Altera Seite:
Ich möchte nun die Bits 0 von sagen wir mal Spalte 3 und 10 logisch UND
Verknüpfen, und mit dem Ausgang dieser Verknüpfung das Bit 7 in Spalte 4
setzen.
Ich denke mal, dass ich die UND-Verknüpfung auf ein Speicherelement
lege, dass ich dann mit negativer Flanke wieder zurücksetze. Den Ausgang
dieses Speichers lege ich So würde dann das Ergebnis beim nächsten
positiven auf den Eingang vom D-Flip-Flop 0 in Spalte 4.
Bei der nächsten positiven CLK-Flanke wird dann der Wert in das
Schieberegister übernommen, und bei der negativen Flanke der
Zwischenspeicher gelöscht.
So viel zu meiner Idee. Leider hapert es an der Umsetzung. Ich habe
schon so einiges ausprobiert, aber komme nicht so richtig weiter.
Das Einzige, was schon geklappt hat, war eine UND-Verknüpfung zwischen
den beiden Bits, die ich dann auf einen Ausgangspin legen konnte. Aber
wie bekomme ich dieses Ergebnis jetzt wieder ins SR zurück?
Könnt ihr mir vielleicht ein paar Tips geben, wie ihr die Sache angehen
würdet?
Gruß
Maik
@Maik Ritter
>Ich möchte nun die Bits 0 von sagen wir mal Spalte 3 und 10 logisch UND>Verknüpfen, und mit dem Ausgang dieser Verknüpfung das Bit 7 in Spalte 4>setzen.
siehe unten.
>Ich denke mal, dass ich die UND-Verknüpfung auf ein Speicherelement>lege, dass ich dann mit negativer Flanke wieder zurücksetze. Den Ausgang
Das gewöhn dir gar nicht erst an. Du solltest dich erstmal mit den
Grundlagen synchroner, sequenzieller Logik befassen. Das läuft alles
wunderbar mit ein Taktflanke.
>den beiden Bits, die ich dann auf einen Ausgangspin legen konnte. Aber>wie bekomme ich dieses Ergebnis jetzt wieder ins SR zurück?
Du brauchst ein weiteres Steuersignal, ich hab es mal load genannt.
Ausserdem ist deine Typdefinition suboptimal. Besser so.
ENTITY shift_8x64_taps IS
PORT (
clk : IN STD_LOGIC;
shift : IN STD_LOGIC;
load : IN STD_LOGIC;
sr_in : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
sr_out : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END shift_8x64_taps;
ARCHITECTURE arch OF shift_8x64_taps IS
TYPE sr_array IS ARRAY (63 DOWNTO 0) OF STD_LOGIC_VECTOR(7 DOWNTO 0);
Array
SIGNAL sr : sr_array;
SIGNAL sr_load : sr_array;
BEGIN
PROCESS (clk)
BEGIN
IF (clk'EVENT and clk = '1') THEN
IF (shift = '1') THEN
sr(63 DOWNTO 1) <= sr(62 DOWNTO 0);
sr(0) <= sr_in;
elsif load='1' then
sr <= sr_load;
END IF;
END IF;
END PROCESS;
sr_out <= sr(63);
-- Logik für Datenverknüpfung, kombinatorisch
process(sr)
begin
-- hier kann jede beliebige Verknüpfung stehen
sr_load <= sr; -- erstmal alle normal zuweisen, Änderungen werden
in den nachfolgenden zeilen überschrieben
sr_load(7)(4) = sr(3)(0) and sr(10(0);
end process;
END arch;
MfG
Falk
Hallo Falk!
Vielen Dank auch heute wieder mal!
>process(sr)
Das ist was, wo ich jetzt wohl nicht drauf gekommen wäre. Ich muss mich
mit den VHDL Konzepten (bzw. der Parallelität der Hardware) erst noch
anfreunden. Bis jetzt habe ich ja nur Software gemacht. . .
Ehrlich gesagt wage ich auch jetzt nur zu ahnen, was da wohl passiert.
Und auch das Symbol im Anhang, was der RTL Viewer aus dem Code generiert
hat kenne ich nicht.
Als ich das Symbol zum ersten Mal in den Altera Data Sheets gesehen
habe, habe ich gedacht, das das ein Mux ist. Aber irgendwie fehlt doch
da die Adressleitung zum Umschalten, welcher Eingang jetzt aktiv ist.
Deswegen ist es wohl kein Mux. Aber was ist es dann?
Gruß
Maik
@Maik Ritter
>Deswegen ist es wohl kein Mux. Aber was ist es dann?
Es IST ein Mux. Ein 1 Bit 2:1 Mux
2 Dateneingänge (links)
1 Steuereingang (oben)
Knapp vorm Ziel verrissen ;-)
MFG
Falk
Okay, okay, ich glaubs dir. . . .
Aber für mich macht dann die Verbindung zum Shift Signal keinen Sinn.
Wenn ich jetzt mit jedem Takt das Schieberegister weiterschieben möchte,
dann ist doch das Shift Signal ständig auf '1', und es kann nie die
Zelle (4)(7) parallel mit dem Ergebnis der UND Verknüpfung geladen
werden, oder?
@Maik Ritter
>Aber für mich macht dann die Verbindung zum Shift Signal keinen Sinn.>Wenn ich jetzt mit jedem Takt das Schieberegister weiterschieben möchte,>dann ist doch das Shift Signal ständig auf '1', und es kann nie die>Zelle (4)(7) parallel mit dem Ergebnis der UND Verknüpfung geladen>werden, oder?
Richtig, denn in der Beschreibung hat Schieben Priorität vor Laden. wenn
du es anders willst, musst du die IF Abfrage vertauschen (erst load,
dann shift).
MfG
Falk
Hallo!
Ich musste mal eben nach Hause fahren. Deswegen melde ich mich jetzt
erst.
Eine Frage hätte ich dann noch zu der Problematik hier: Egal, wie rum
ich es mache, ich bekomme kein kontinuierliches Schieben durch die
Register hin, oder? Ich also pro Takt entweder nur schieben, oder nur
laden.
Gibt es auch eine Möglichkeit beides Gleichzeitig zu machen? Geladen
werden dann eben nur die D-FFs, die auch wirklich über ein MUX am
Eingang verfügen.
Die anderen bekommen ihr Signal nach wie vor von den vorhergehenden
D-FFs.
Hmmmm, eine Idee?
Gruß
Maik
@ Maik Ritter
>Die anderen bekommen ihr Signal nach wie vor von den vorhergehenden>D-FFs.>Hmmmm, eine Idee?
Na DAS solltest du jetzt aber alleine hinbekommen. Schau dir mal das
VHDL an.
MfG
Falk
Hallo Falk!
Ich hoffe du bist in der Nähe . . .
Um es kurz zu machen: Ich bekomme es nicht hin.
Egal, was ich versuche, entweder spuckt der Compiler schon einen
Syntaxfehler aus, oder mein ganzes Schieberegister ist weg . . . (ich
habe dann im RTL Viewer nicht mehr 512 D-FFs sondern nur noch 11 oder so
. . . )
Im RTL Viewer sehe ich ja, dass die D-FFs auch einen asynchronen
Ladeeingang haben. Den könnte ich ja eigentlich benutzen und mit meiner
UND Verknüpfung verbinden. Nur wie?
Du musst mir ja nicht gleich die Ganze Lösung präsentieren. Vielleicht
reicht ja auch schon ein Tip an welcher Stelle ich ran muss.
Auf alle Fälle stört mich dieses "ENTWEDER schieben ODER laden" pro
Takt. Es soll halt geschoben werden und das Ergebnis der UND Verknüpfung
gleich an die entsprechende Stelle geladen werden.
Sorry, wenn ich mich blöd anstelle, aber ich finde echt nichts in meinen
VHDL Unterlagen, die mir weiterhelfen . . .
Gruß
Maik
@ Maik Ritter
>Ich hoffe du bist in der Nähe . . .
I'll be there for you . . . ;-)
>Um es kurz zu machen: Ich bekomme es nicht hin.
Hmm.
>Im RTL Viewer sehe ich ja, dass die D-FFs auch einen asynchronen>Ladeeingang haben. Den könnte ich ja eigentlich benutzen und mit meiner>UND Verknüpfung verbinden. Nur wie?
Nein.
>Du musst mir ja nicht gleich die Ganze Lösung präsentieren. Vielleicht>reicht ja auch schon ein Tip an welcher Stelle ich ran muss.
Kleiner Denkanstoss.
Bei jedem Takt laden die FlipFlops einen neuen Wert. Einige sollen nur
als Schieberegister arbeiten. Diese laden den Wert ihres Vorgängers.
Einige sollen als Speicher für logisch verknüpfte Signale arebeiten.
Diese laden eben die logischen Verknüpfungen.
Du kannst im Prinzip eine sehr lange Liste schreiben, welchen Wert jedes
einzelne FlipFlop laden soll. Die Fortgeschrittenen sparen sich durch
clevere Formulierungen viel Schreibarbeit.
Na, dämmerts?
>Auf alle Fälle stört mich dieses "ENTWEDER schieben ODER laden" pro>Takt. Es soll halt geschoben werden und das Ergebnis der UND Verknüpfung>gleich an die entsprechende Stelle geladen werden.
Das entweder Schieben oder Laden enstand nur in dem Beispiel. Das kannst
du wieder rausnehmen. Alles was du brauchst ist eine 0815
Signalzuweisung in einem getakteten Prozess.
>Sorry, wenn ich mich blöd anstelle, aber ich finde echt nichts in meinen>VHDL Unterlagen, die mir weiterhelfen . . .
Das ist ein Problem des Grundverständnisses. Wie arbeitet synchrone
Logik?
MFG
Falk
Vielen Dank, dass du solche Geduld mit mir hast.
Langsam reift in mir eine Idee. Dazu nur eine kleine Frage: Das Schieben
der Registerinhalte (was ja nach wie vor noch 98% meiner Applikation
ausmacht) realisiere ich dann nicht mehr über ein einfaches zuweisen wie
hier:
1
sr(63DOWNTO1)<=sr(62DOWNTO0);
sondern ich muss nun für jedes FF einzeln entscheiden, ob es den
Vorgängerwert übernimmt, oder anders geladen wird, oder?
Ich frage nur vorsichtshalber nach und fange jetzt gleich mit dem
ausprobieren an. Wenn ich nach wie vor diesen Code als Grundlage nehmen
soll, dann kannst du ja die Notbremse ziehen.
Gruß
Maik
@ Maik Ritter
>Langsam reift in mir eine Idee. Dazu nur eine kleine Frage: Das Schieben>der Registerinhalte (was ja nach wie vor noch 98% meiner Applikation>ausmacht) realisiere ich dann nicht mehr über ein einfaches zuweisen wie>hier:>sr(63 DOWNTO 1) <= sr(62 DOWNTO 0);
Doch, das ist schonmal richtig.
>sondern ich muss nun für jedes FF einzeln entscheiden, ob es den>Vorgängerwert übernimmt, oder anders geladen wird, oder?
Das ist auch richtig. Der Knackpunt ist, es möglichs mit wenig Aufwand
hinzuschreiben. Schliesslisch willst du nicht für 64x8 Bit jeweils eine
eigene Zuweiseung schreiben.
Noch ein kleiner Tip.
In einem kombinatorischen Prozess funktioniert Logik wie in Software.
Zuweisungen die weiter unten stehen überschrieben Zuweisungen die weiter
oben stehen.
Nun aber!
>ausprobieren an. Wenn ich nach wie vor diesen Code als Grundlage nehmen>soll, dann kannst du ja die Notbremse ziehen.
Der Code den ich geschrieben habe kannst du verwenden. Schmeiss die IF
mit shift und load raus.
MFG
Falk
Habe auch schon ein neues Extra mit eingebaut. So sieht es auf den
ersten Blick schon mal genau so aus, wie ich es haben wollte.
Jetzt vielleicht noch mal eine praktische Frage: Funktioniert das auch?
Angenommen "(sr(3)(0) and sr(10)(0))" ist '1' nach dem letzten Takt.
Dann wird dies aber erst im nächsten Takt von sr(4)(7) übernommen. In
diesem nächsten Takt kann sich aber auch "(sr(3)(0) and sr(10)(0))"
schon wieder so ändern, dass es nicht mehr '1' ist. Kann man denn 100%ig
sagen, dass die alte '1' übernommen wird. Ich denke mal im Simulator
wird das so sein, aber in der Praxis?
Was sagst du als erfahrener Hase dazu?
Bis hier hin aber wirklich erst mal vielen Dank für deine tolle Hilfe!!!
Gruß
Maik
@ Maik Ritter
>sr(63 DOWNTO 1) <= sr(62 DOWNTO 0);>sr(0)(7) <= sr(5)(5) and sr(10)(5);>sr(4)(7) <= (sr(3)(0) and sr(10)(0)) or sr(3)(7);>sr(0) <= sr_in;
Heureka!
>Jetzt vielleicht noch mal eine praktische Frage: Funktioniert das auch?
Ja. Fast.
Dein
sr(0) <= sr_in;
in der 4. Zeile macht dir dein
sr(0)(7) <= sr(5)(5) and sr(10)(5);
unwirksam. Da musst du die Reihenfolge vertauschen.
>Angenommen "(sr(3)(0) and sr(10)(0))" ist '1' nach dem letzten Takt.>Dann wird dies aber erst im nächsten Takt von sr(4)(7) übernommen. In>diesem nächsten Takt kann sich aber auch "(sr(3)(0) and sr(10)(0))">schon wieder so ändern, dass es nicht mehr '1' ist. Kann man denn 100%ig>sagen, dass die alte '1' übernommen wird. Ich denke mal im Simulator>wird das so sein, aber in der Praxis?
Auch in der Praxis. Es dauert* ja eine kleine Weile, bis die neuen Daten
aus den FLipFlop rauskommen. Da sind die alten Daten längst übernommen
worden.
>Was sagst du als erfahrener Hase dazu?
Gut durchgekämpft! Weiter so!
MFG
Falk
*die FlipFlops in heutigen FPGAs brauchen dazu weniger als eine
Nanosekunde. Aber das passt schon.