mikrocontroller.net

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


Autor: Der Daimlerfahrer (daimlerfahrer)
Datum:

Bewertung
0 lesenswert
nicht 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:
entity Modulwahl is
    Port ( Takteingang : in std_logic;
           Eingang : in std_logic_vector(15 downto 0);
       Modul1 : out std_logic_vector(13 downto 0);
       Modul2 : out std_logic_vector(13 downto 0);
       Modul3 : out std_logic_vector(13 downto 0);
       Modul4 : out std_logic_vector(13 downto 0)
       );
end Modulwahl;
--
Verteil1 : process(Takteingang)
begin
  if rising_edge(Takteingang) then
         case Eingang(1 downto 0) is
            when "00" => Modul1 <= Eingang(15 downto 2);
            when "01" => Modul2 <= Eingang(15 downto 2);
            when "10" => Modul3 <= Eingang(15 downto 2);
            when "11" => Modul4 <= Eingang(15 downto 2);
            when others => 
         end case;
  end if;
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:
entity Signalwahl is
    Port ( Takteingang : in std_logic;
           Eingang : in std_logic_vector(13 downto 0);
       Signal1 : out std_logic_vector(10 downto 0);
       Signal2 : out std_logic_vector(10 downto 0);
       Signal3 : out std_logic_vector(10 downto 0);
       Signal4 : out std_logic_vector(10 downto 0);
       Signal5 : out std_logic_vector(10 downto 0);
       Signal6 : out std_logic_vector(10 downto 0);
       Signal7 : out std_logic_vector(10 downto 0);
       Signal8 : out std_logic_vector(10 downto 0)
       );
end Signalwahl;
--
Verteil2 : process(Takteingang)
begin
  if rising_edge(Takteingang) then
           case Eingang(2 downto 0) is
              when "000" => Signal1 <= Eingang(13 downto 3);
              when "001" => Signal2 <= Eingang(13 downto 3);
              when "010" => Signal3 <= Eingang(13 downto 3);
              when "011" => Signal4 <= Eingang(13 downto 3);
              when "100" => Signal5 <= Eingang(13 downto 3);
              when "101" => Signal6 <= Eingang(13 downto 3);
              when "110" => Signal7 <= Eingang(13 downto 3);
              when "111" => Signal8 <= Eingang(13 downto 3);
              when others => 
           end case;
  end if;
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!

Autor: Klugscheisser (Gast)
Datum:

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

Autor: Klugscheisser (Gast)
Datum:

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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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:
Verteil1 : process(Eingang)  --- Sens-List anpassen !!
begin
         case Eingang(1 downto 0) is
            when "00" => Modul1 <= Eingang(15 downto 2);
            when "01" => Modul2 <= Eingang(15 downto 2);
            when "10" => Modul3 <= Eingang(15 downto 2);
            when "11" => Modul4 <= Eingang(15 downto 2);
            when others => 
         end case;
end process;

Autor: Der Daimlerfahrer (daimlerfahrer)
Datum:

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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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:
Verteil1 : process(Eingang)  --- Sens-List anpassen !!
begin
   case Eingang(1 downto 0) is
      when "00" => Modul1 <= Eingang(15 downto 2);
      when "01" => Modul2 <= Eingang(15 downto 2);
      when "10" => Modul3 <= Eingang(15 downto 2);
      when "11" => Modul4 <= Eingang(15 downto 2);
      when others => 
   end case;
end process;

VerteilMEM : process(Takteingang)
begin
   if rising_edge(Takteingang) then
      Modul1mem <= Modul1;
      Modul2mem <= Modul2;
      Modul3mem <= Modul3;
      Modul4mem <= Modul4;
   end if;
end process;
Aber da solltest du dir schon überlegen, ob du nicht einen (1) zentralen 
Adressdecoder bauen willst. Sieht irgendwie unnötig aus...

Autor: Der Daimlerfahrer (daimlerfahrer)
Datum:
Angehängte Dateien:

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

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.