mikrocontroller.net

Forum: FPGA, VHDL & Co. Schieberegister vereinzelt parallel laden


Autor: Maik Ritter (kiamur)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;

ENTITY shift_8x64_taps IS
PORT (
  clk :       IN STD_LOGIC;
  shift :       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

SUBTYPE sr_width IS STD_LOGIC_VECTOR(7 DOWNTO 0); -- Bits
TYPE sr_length IS ARRAY (63 DOWNTO 0) OF sr_width; -- Spalten

SIGNAL sr : sr_length;

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;
      END IF;
    END IF;
  END PROCESS;

  sr_out <= sr(63);

END arch;
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

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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

Autor: Maik Ritter (kiamur)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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

Autor: Maik Ritter (kiamur)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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

Autor: Maik Ritter (kiamur)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ 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

Autor: Maik Ritter (kiamur)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ 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

Autor: Maik Ritter (kiamur)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
sr(63 DOWNTO 1) <= sr(62 DOWNTO 0);

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

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ 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

Autor: Maik Ritter (kiamur)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wow, ich hab's! :-)
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;

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

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.