Forum: FPGA, VHDL & Co. 2bit Piso. Getaktet einlesen & ausgeben


von Andree (Gast)


Lesenswert?

Hallo,
ich versuche mal meine Überlegung zu schildern, ich weiß das es das 
sicherlich schon zu häufe gibt aber selbst verstehen is besser als 
kopieren.

Also meine überlegung ist das ich ein 2 bit Piso benötige um
a und b gleichzeitig einzulesen und dann nacheinander auszugeben mitg 
lsb first.

Die Daten liegen bei jeder steigenden Taktflanke an und sollen 
demensprechen auf dem gleichen takt wieder ausgegeben werden. Mir ist 
klar das hier eine Verzögerung stattfindet. DIe Daten liegen ja 
zeitgleich an und erst soll a dann ausgegeben werden einen takt und dann 
b einen takt. währendessen kommen aber ja schon wieder beim zweiten Takt 
neue Daten rein.

Ich habe mir das wie folgt vorgestellt:
Data : in std_logic_vector (1 downto 0);
Clock : in std_logic;
Serial : out std_logic;
...
Signal shift : std:logic_vector (1 downto 0);

Process (Clock)
Begin
IF(Clock'event AND Clock='1') THEN
   shift<= Data(0) & Data(1);
ELSE
   shift<= shift(0) & shift(1);
END IF;
END Process;

Serial<= shift(0);

ich denke aber noch das ich

shift<= Data(0) & Data(1) von einer Bedingung abhängig machen muss. Also 
parallel laden.
If(Pl='1') THEN
shift<= Data(0) & Data(1);
ELSE
...

Nur wie übergeb ich die Anweisung wenn er jeden Takt bzw bei jeder 
steigenden Taktflanke laden soll und dann getaktet nacheinander ausgibt.
Irgendwo hänge ich mit dem verstehen bzw umsetzung.
Wenn jemand mit mir dies detailiert durchgehen würde, würde ich mich 
sehr freuen.

Vielen Dank

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Andree schrieb:
> Also meine überlegung ist das ich ein 2 bit Piso benötige um
> a und b gleichzeitig einzulesen
Das geht nicht. Oder wie definierst du "Gleichzeitig"?

> Wenn jemand mit mir dies detailiert durchgehen würde, würde ich mich
> sehr freuen.
Zeichne DU mal auf, wie die Bits hereinkommen, und wie sie bezogen auf 
den Takt wieder rausmüssen. Und auch, wie man erkennen kann, ob da am 
Ausgang gerade das Bit 0 oder das bit 1 anliegt...

Ich würde das ansatzweise mal so machen:
1
Data : in std_logic_vector (1 downto 0);
2
Clock : in std_logic;
3
Serial : out std_logic;
4
...
5
Signal merker: std_logic_vector (1 downto 0);
6
Signal toggle : std_logic := '0';
7
8
Process (Clock) begin
9
  IF rising_edge(Clock) THEN
10
    toggle <= not toggle; -- mitzählen
11
    if (toggle='1') then  -- jeden 2. Takt das Eingangswort einlesen
12
      merker <= Data;
13
    end if;
14
  END IF;
15
END Process;
16
17
Serial<= merker(0) when toggle='0' else merker(1);

Sowas geht sicher nicht:
1
IF(Clock'event AND Clock='1') THEN
2
   shift<= Data(0) & Data(1);        -- wenn ein Taktimpuls anliegt mach das hier
3
ELSE
4
   shift<= shift(0) & shift(1);      -- den Rest der Zeit mach das hier
5
END IF;
Weil ein Takt per Definition genau 0 ps lang dauert, wird hier dauernd 
die ELSE aufgerufen. Kurz: du hättest eine kombinatorische Schleife.... 
:-/
Zum Glück kann das der Synthesizer aber nicht so ohne weiteres umsetzen 
und du bekommst eine entsprechende Meldung.

von Andree (Gast)


Angehängte Dateien:

Lesenswert?

Hmm das ist jetzt das Beispiel mit meinem Code´was man auf dem Bild 
sehen kann. Der versatz macht nichts und wie man sieht schluckt er auch 
den ersten Wert bei der Ausgabe.

Aber wie gesagt es liegen 2 Daten an und diese sollen seriell ausgegeben 
werden. a oder wie in dem bild d0 soll hierbei lsb sein. Man muss nicht 
wissen welches nun Lsb ist es geht nur darum das wenn er anfängt 
rauszuschicken immer d0 bzw a als erstes rauschiebt bevor d1 kommt und 
danach schon die neuen Werte.

Bei deinem Beispiel steht ja Eingangswort jeden 2ten Takt lesen aber ich 
müsste jeden Takt dies machen. UNd dann auch wenn bissl verzögert dieses 
auf dem gleichen Takt ausgeben.

Ich weis nicht ob ich mich so recht richtig ausdrücke...aber ich hoffe 
man versteht worum es mir geht!?

von Andree (Gast)


Angehängte Dateien:

Lesenswert?

Ich seh grade das ich den clock zu meinem Bild abgeschnitten habe :D
PL steht für "parallel" load

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Andree schrieb:
> Bei deinem Beispiel steht ja Eingangswort jeden 2ten Takt lesen aber ich
> müsste jeden Takt dies machen.
Das war mit den bis dahin bekannten Informationen so ersichtlich.

Aber du hast ja schon eine Beschreibung, die das macht, was du willst, 
oder wie?

Für die neue Beschreibung würde ich das mal so ansetzen:
1
Data   : in std_logic_vector (1 downto 0);
2
Clock  : in std_logic;
3
PL     : in std_logic;
4
Serial : out std_logic;
5
...
6
Signal merker: std_logic := '0';
7
Signal PLold:  std_logic := '0';
8
9
Process (Clock) begin
10
  IF rising_edge(Clock) THEN
11
    if (PL='1' and PLold='0') then  -- Flankenerkennung PL
12
      Serial <= Data(0);            -- steigende Flanke --> LSB ausgeben
13
      merker <= Data(1);            -- MSB merken
14
    else
15
      Serial <= merker;             -- nächster Takt: MSB ausgeben
16
    end if;
17
    PLold <= PL;
18
  END IF;
19
END Process;

von Andree (Gast)


Lesenswert?

Und jetzt kommt mir die Frage auf könnte man dies auch irgendwie 
realisieren ohne extra PL für das Laden zu benutzen quasi das man sich 
intern dieses Signal auch noch in Abhängigkeit von der Clock generiert?

Ja die beschreibung die ich mir überlegt hatte benötigt halt das PL und 
ich bin auf der Suche bzw versuche eine Umsetzung wo ich als  nur

Data   : in std_logic_vector (1 downto 0);
Clock  : in std_logic;

und Ausgang

Serial : out std_logic;

habe. Aber irgendwie wills mir grad noch nicht so gelingen oder geh ich 
da grad mit dem falschen Ansatz dran?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Andree schrieb:
> Aber irgendwie wills mir grad noch nicht so gelingen oder geh ich
> da grad mit dem falschen Ansatz dran?
Das geht auch gar nicht...
Denn du weißt dann nicht, wann das 0. und wann das 1. Bit übertragen 
wird.

von Andree (Gast)


Angehängte Dateien:

Lesenswert?

es muss eigentlich immer erst das 0te bit bzw a bit gesendet werden. 
also sobald es losgeht. ok ich könnte ein Signal noch anlegen das angibt 
wann gestartet werden soll und dieses geht erst wieder auf 0 wenn keine 
Daten mehr anliegen.

Um nochmal eben das zu verdeutlichen oder nachzufragen...so wie auf dem 
Bild ist es also nicht möglich? Nur wenn Ich zusätzlich Pl mitbenutzen 
würde und dieser toggelt?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Andree schrieb:
> sobald es losgeht.
Das gibt es nicht.
Überleg dir mal was "sobald es losgeht" bedeutet, wenn du keinerlei 
Synchronisationsmöglichkeit hast, und irgendwer z.B. einen Takt 
verpasst.

> ok ich könnte ein Signal noch anlegen das angibt wann gestartet werden
> soll und dieses geht erst wieder auf 0 wenn keine Daten mehr anliegen.
Nur so macht das Sinn. Und damit wird die Sache auch sehr einfach. 
Probiers mal so:
1
Data   : in std_logic_vector (1 downto 0);
2
Clock  : in std_logic;
3
Send   : in std_logic;   -- steigende Flanke zeigt das erste Bit 0 an, uebertragen wird, solange Send=1
4
Serial : out std_logic;
5
...
6
Signal merker: std_logic_vector(1 downto 0) := "00";
7
Signal sold:  std_logic := '0';
8
9
Process (Clock) begin
10
  IF rising_edge(Clock) THEN
11
    if (Send='1') then
12
      if (sold='0') then    -- Flankenerkennung 
13
        merker <= Data;     -- Wort merken
14
      else
15
        merker <= merker(0) & merker (1); -- Bits tauschen
16
      end if;
17
      sold <= not sold;
18
    else
19
      sold <= '0';
20
    end if;
21
  END IF;
22
END Process;
23
24
Serial <= merker(0);  -- LSB ausgeben

von Andree (Gast)


Lesenswert?

vielen Dank es haut nun hin :)

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
Noch kein Account? Hier anmelden.