Forum: FPGA, VHDL & Co. SPI "stufenweise" auswerten


von Der D. (daimlerfahrer)


Lesenswert?

Servus zusammen,

ich hatte letztens einige Schwierigkeiten meine SPI Schnittstelle zum 
Laufen zu bekommen. Inzwischen werden die Daten im FPGA zwar übernommen, 
meine Auswertung klappt jedoch nicht sauber.

Ich möchte aus "Symmetriegründen" die Daten stufenweise auswerden.
Bedeutet:
Im ersten Schritt werte ich die untersten 2 Bit aus und entscheide 
daran, in welches Modul (insg. 4 Module) meine Daten gehören. Ich werde 
also wie folgt aus und leite den "Rest" des Eingangs weiter:
1
entity Modulwahl is
2
    Port ( Takteingang : in std_logic;
3
           Eingang : in std_logic_vector(15 downto 0);
4
       Modul1 : out std_logic_vector(13 downto 0);
5
       Modul2 : out std_logic_vector(13 downto 0);
6
       Modul3 : out std_logic_vector(13 downto 0);
7
       Modul4 : out std_logic_vector(13 downto 0)
8
       );
9
end Modulwahl;
10
--
11
Verteil1 : process(Takteingang)
12
begin
13
  if rising_edge(Takteingang) then
14
         case Eingang(1 downto 0) is
15
            when "00" => Modul1 <= Eingang(15 downto 2);
16
            when "01" => Modul2 <= Eingang(15 downto 2);
17
            when "10" => Modul3 <= Eingang(15 downto 2);
18
            when "11" => Modul4 <= Eingang(15 downto 2);
19
            when others => 
20
         end case;
21
  end if;
22
end process;

Nach diesem Schritt möchte ich in jedem Modul gleichermaßen die Signale 
(insgesamt 8 Signale) zuweisen.
Das beideutet in diesem Fall, dass "Modul1" der Eingang der Signalwahl 
ist.
Dazu werte ich wiederum die untersten 3 Bit aus und schiebe den "Rest" 
an Daten weiter:
1
entity Signalwahl is
2
    Port ( Takteingang : in std_logic;
3
           Eingang : in std_logic_vector(13 downto 0);
4
       Signal1 : out std_logic_vector(10 downto 0);
5
       Signal2 : out std_logic_vector(10 downto 0);
6
       Signal3 : out std_logic_vector(10 downto 0);
7
       Signal4 : out std_logic_vector(10 downto 0);
8
       Signal5 : out std_logic_vector(10 downto 0);
9
       Signal6 : out std_logic_vector(10 downto 0);
10
       Signal7 : out std_logic_vector(10 downto 0);
11
       Signal8 : out std_logic_vector(10 downto 0)
12
       );
13
end Signalwahl;
14
--
15
Verteil2 : process(Takteingang)
16
begin
17
  if rising_edge(Takteingang) then
18
           case Eingang(2 downto 0) is
19
              when "000" => Signal1 <= Eingang(13 downto 3);
20
              when "001" => Signal2 <= Eingang(13 downto 3);
21
              when "010" => Signal3 <= Eingang(13 downto 3);
22
              when "011" => Signal4 <= Eingang(13 downto 3);
23
              when "100" => Signal5 <= Eingang(13 downto 3);
24
              when "101" => Signal6 <= Eingang(13 downto 3);
25
              when "110" => Signal7 <= Eingang(13 downto 3);
26
              when "111" => Signal8 <= Eingang(13 downto 3);
27
              when others => 
28
           end case;
29
  end if;
30
end process;

Nun sollten nach meinem Empfinden die benötigten Daten-Bit auf die 
entsprechende Leitung verteilt sein und ich sollte damit weiter arbeiten 
können.
Leider ist dem nicht so, sondern es werden "alte" (also im Schritt zuvor 
gesendete) Daten auf die Signale übergeben (schwer zu beschreiben, als 
würden die Daten immer verzägert eintreffen).

Habt ihr Vorschläge, was an dieser Auswertung des SPI Probleme machen 
kann?
Wenn ich den SPI komplett auf einmal auswerte, habe ich diese Probleme 
nicht - die kommen erst mit meiner schrittweisen Auswertung.

Danke euch schonmal!

von Klugscheisser (Gast)


Lesenswert?

Naja, das ist ganz normal.
Beachte, das beide entities ja jeweils auf die gleiche Flanke (des 
vermutlich gleichen Taktes reagieren).

Während also Modulwahl1 seine Eingänge weiterschaltet wird gleichzeitig 
auch Signalwahl seine Eingänge weiterschalten. An letzteren liegt aber 
das Ergebnis der vorherigen Auswahl in der entitiy Modulwahl1.

Wie sollte das auch anders sein?
Modulwahl braucht seine Zeit um was zu tun.
Signalwahl kann nur unter schon vorhandenen Signalen wählen nicht 
unter welchen die gerade gleichzeitig woanders berechnet werden.

Warum willst Du das denn aufteilen wenn es doch "flat" schon 
funktioniert. Das ist sicherlich auch effektiver (sprich kleiner) als 
zwei einzelne Multiplexer. So belegt das eine Menge Signale (im 
VHDL-Sinn).

von Klugscheisser (Gast)


Lesenswert?

Irgendwie sieht das auch merkwürdig aus.
Ich gehe davon aus, das Du irgendwelche Befehle oder sowas erkennen 
willst und dazu für jeden Befehl ein eigenes Erkennungsmodul und 
Auswertungsmodul schreiben willst. Das führt aber hier dazu, das du 
insgesamt 88 + 56 Signale erzeugst.
Es wäre, denke ich besser die Erkennung und Verarbeitung auf einem 
einzigne Satz von Signalen aufzubauen.

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


Lesenswert?

> Leider ist dem nicht so, sondern es werden "alte" (also im Schritt
> zuvor gesendete) Daten auf die Signale übergeben (schwer zu beschreiben,
> als würden die Daten immer verzägert eintreffen).
Mein Glückwunsch, du hast den Begriff "Latency" entdeckt.
Durch die beiden getakteten Prozesse hast du Register zwischen die 
beiden Stufen geschaltet. Sieh dir mal die RTL-Schematics zu deiner 
Beschreibung an.

Im der "Modulwahl" wird mit dem jetzigen Takt eines der Module 1-4 
ausgewählt und dieser Wert in Registern gespeichert. Beim nächsten Takt 
wird im Modul "Signalwahl" mit diesen Werten gearbeitet.

Schreib die Modulwahl mal kombinatorisch, das wird helfen:
1
Verteil1 : process(Eingang)  --- Sens-List anpassen !!
2
begin
3
         case Eingang(1 downto 0) is
4
            when "00" => Modul1 <= Eingang(15 downto 2);
5
            when "01" => Modul2 <= Eingang(15 downto 2);
6
            when "10" => Modul3 <= Eingang(15 downto 2);
7
            when "11" => Modul4 <= Eingang(15 downto 2);
8
            when others => 
9
         end case;
10
end process;

von Der D. (daimlerfahrer)


Lesenswert?

Lothar Miller wrote:
> Schreib die Modulwahl mal kombinatorisch, das wird helfen:

Okay mit dem kombinatorischen Ansatz werden die Daten zumindest an die 
richtige Stelle geschrieben - bedanke mich für diesen Hinweis! Da hab 
ich wieder was gelernt.

Jetzt bleiben mir leider die Daten an den jeweiligen Ausgängen nicht 
mehr erhalten, sondern werden bei einem neuen Datenpaket zurückgesetzt 
auf den Urspungswert.
Da werde ich dann wohl ein Register wieder einbauen müssen :D

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


Lesenswert?

> Da werde ich dann wohl ein Register wieder einbauen müssen :D
Richtig, und die Latency in Kauf nehmen ;-)

Wenn du die Werte auch gespeichert brauchst, dann mach das doch 
parallel:
1
Verteil1 : process(Eingang)  --- Sens-List anpassen !!
2
begin
3
   case Eingang(1 downto 0) is
4
      when "00" => Modul1 <= Eingang(15 downto 2);
5
      when "01" => Modul2 <= Eingang(15 downto 2);
6
      when "10" => Modul3 <= Eingang(15 downto 2);
7
      when "11" => Modul4 <= Eingang(15 downto 2);
8
      when others => 
9
   end case;
10
end process;
11
12
VerteilMEM : process(Takteingang)
13
begin
14
   if rising_edge(Takteingang) then
15
      Modul1mem <= Modul1;
16
      Modul2mem <= Modul2;
17
      Modul3mem <= Modul3;
18
      Modul4mem <= Modul4;
19
   end if;
20
end process;
Aber da solltest du dir schon überlegen, ob du nicht einen (1) zentralen 
Adressdecoder bauen willst. Sieht irgendwie unnötig aus...

von Der D. (daimlerfahrer)


Angehängte Dateien:

Lesenswert?

Ich habe 4 Module. Davon hat jedes Modul 8 Signale. Jedes Signal hat 2
Flanken.

Ich wollte nun Einen Entscheider für die Flanke, einen für das Signal
und einen für das Modul benutzen. Das steckt dahinter.
Da sich alles wiederholt habe ich diese stufenweise Entscheidung für
einfacher gehalten, da ich die Entscheiderblöcke (zB für Signal 1-8)
direkt 4 mal hinter die Modulwahl klemmen kann und somit das ganze
wiederverwenden.

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.