Forum: FPGA, VHDL & Co. VHDL - Vertauschte Endianness


von M. V. (mvollmer)


Lesenswert?

Hallo zusammen,

ich habe hier ein Projekt bei dem ein PIC32 und ein CPLD über SPI 
kommunizieren. Das CPLD schaltet je nach Daten die vom PIC kommen 
bestimmte Eingänge auf Ausgänge.

Jedoch habe ich nun folgendes Problem.

PIC sendet 0x0001 (MSB 0000 0000 0000 0001 LSB)

Diese werden wie folgt in einen logic vector gespeichert:
1
architecture FOO_beh of FOO is
2
3
signal SpiReg               : std_logic_vector (15 downto 0):=(others=>'0');
4
signal bar0                : std_logic_vector (1 downto 0):=(others=>'0');
5
6
p40: process (SpiClk)
7
begin
8
    if rising_edge (SpiClk) then
9
        if nSpiCs='0' then
10
            SpiReg(15 downto 1)<=SpiReg(14 downto 0);
11
            SpiReg(0)<=MOSI;
12
            
13
        end if;
14
    end if;
15
end process p40;

Dann sollen je nachdem was für Daten gesendet wurden ein Eingang auf 
einen Ausgang gesetzt werden:
1
bar0<=SpiReg (1 downto 0);
2
3
pBAR0: process (bar0, fooIn0, fooIn1, fooIn2, fooIn3)
4
begin
5
    case bar0 is
6
        when "00" => foo0Out<=fooIn0;
7
        when "01" => foo0Out<=fooIn1;
8
        when "10" => foo0Out<=fooIn2;
9
        when "11" => foo0Out<=fooIn3;
10
        when others => foo0Out<='0';
11
    end case;
12
end process pBAR0;
Bei 0x0001 (MSB 0000 0000 0000 0001 LSB), würden ich jetzt erwarten das 
der Ausgang fooIn1 auf foo0Out geschalten wird. Jedoch ist dies nicht 
so, sondern es wird auf fooIn2 geschalten.

Sende ich nun ein 0x0002 (MSB 0000 0000 0000 0010 LSB), ist es genau 
umgekehrt und der Ausgang wird auf fooIn1 geschaltet, so wie ich es bei 
0x0001 erwartet hätte.

Aber wo ist hier der Fehler? Es scheint ja die Endianness zu sein. Aber 
wo werden die 2 Bits vertauscht?

Der Quelltext wurde nur auf das nötigste beschränkt um es zu 
vereinfachen.
Ich danke für jeden Hinweis oder jede Aufklärung :)

LG
mvollmer

: Bearbeitet durch User
von Duke Scarring (Gast)


Lesenswert?

M. Vollmer schrieb:
> Der Quelltext wurde nur auf das nötigste beschränkt
Etwas zuviel gekürzt.
Wie sieht die Zuweisung zwischen SpiReg und SwFp0 aus?

Ansonsten kannst Du Dein Schieberegister auch andersrum schieben lassen:
1
      SpiReg <= MOSI & SpiReg(15 downto 1);

Duke

von M. V. (mvollmer)


Lesenswert?

Sorry, es handelte sich bei SwFp0 um bar0. Habs oben im Code geändert.

LG
mvollmer

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


Lesenswert?

M. Vollmer schrieb:
> es wird auf fooIn2 geschalten.
Es wird "geschaltet".

Duke Scarring schrieb:
> Ansonsten kannst Du Dein Schieberegister auch andersrum schieben lassen:
> SpiReg <= MOSI & SpiReg(15 downto 1);
Eher andersrum:
1
            SpiReg<=SpiReg(14 downto 0)&MOSI;
Aber das ist hier nicht das Problem. Und auch nicht, dass das 
Schieberegister irgendwas vertauscht. Und zudem bezieht sich Endianess 
auf die Position von Bytes im Wort.

M. Vollmer schrieb:
> Bei 0x0001 (MSB 0000 0000 0000 0001 LSB), würden ich jetzt erwarten das
> der Ausgang fooIn1 auf foo0Out geschalten wird. Jedoch ist dies nicht
> so, sondern es wird auf fooIn2 geschalten.
>
> Sende ich nun ein 0x0002 (MSB 0000 0000 0000 0010 LSB), ist es genau
> umgekehrt und der Ausgang wird auf fooIn1 geschaltet, so wie ich es bei
> 0x0001 erwartet hätte.
Was kommt jeweils nach dem letzten Bit? Kann es sein, dass da einfach 
nach dem gewollten Ende der Übertragung noch irgendwas reingetaktet 
wird?

: Bearbeitet durch Moderator
von M. V. (mvollmer)


Angehängte Dateien:

Lesenswert?

Lothar Miller schrieb:
> Was kommt jeweils nach dem letzten Bit? Kann es sein, dass da einfach
> nach dem gewollten Ende der Übertragung noch irgendwas reingetaktet
> wird?

Der PIC sendet zyklisch immer wieder den selben Wert (zum Testen). Ich 
habe mit dem Scope mal die Übertragung aufgenommen, dort sieht alles 
sehr gut aus.
(CH2/4 bitte ignorieren). Der Chip Select ist auch OK. Jedoch auf diesem 
Screen nicht zu sehen.

Es ist so das von den 16 Bits die per SPI reinkommen, immer Gruppen aus 
2 Bits interpretiert werden. Es gibt 4 Eingänge(fooIn0-3) und 7 
Ausgänge(foo0Out - foo6Out). D.h. von den 16 Bits die Übertragen werden, 
werden die 2 MSB nicht interpretiert.

Die Interpretation der restlichen 12 Bits habe ich weggelassen, da sich 
der Quelltext nur mit anderen variablen widerholt.

Meine Vermutung war halt das durch:
1
bar0<=SpiReg (1 downto 0);
 und "01" bzw "10" sich die Bits vertauschen bzw. in der falschen 
reihenfolge interpretiert werden.

Aber eigentlich sieht es ja richtig aus.

Vielen Dank

LG
mvollmer

: Bearbeitet durch User
von Duke Scarring (Gast)


Lesenswert?

Lothar Miller schrieb:
> Eher andersrum:            SpiReg<=SpiReg(14 downto 0)&MOSI;
So stand es ja im Original schon da.

M. Vollmer schrieb:
> habe mit dem Scope mal die Übertragung aufgenommen, dort sieht alles
> sehr gut aus.
Welcher Wert wurde denn hier übertragen?

Duke

von M. V. (mvollmer)


Lesenswert?

> M. Vollmer schrieb:
>> habe mit dem Scope mal die Übertragung aufgenommen, dort sieht alles
>> sehr gut aus.
> Welcher Wert wurde denn hier übertragen?
>
> Duke

0x24E4

Lg
mvollmer

von Valko (Gast)


Lesenswert?

Hast du "SpiClk" und "MOSI" Constraints richtig gesetzt? Verwendest du 
den Clock von draussen oder wird irgendwas synchronisiert?

Gruss

von M. V. (mvollmer)


Angehängte Dateien:

Lesenswert?

Valko schrieb:
> Hast du "SpiClk" und "MOSI" Constraints richtig gesetzt?
> Verwendest du
> den Clock von draussen oder wird irgendwas synchronisiert?
>
> Gruss

Der Clock kommt von außen, um genau zu sein vom PIC selbst.
Und die Constraints sind auch richtig.

Ich habe die Daten auch direkt über
1
MISO<=MOSI;
an den MISO weitergeleitet. Und auch am MISO Pin kommen die Daten wie 
erwartet wieder raus.

Was mir grade jedoch aufgefallen ist, das die Daten am MISO um einen 
halben Clock früher rausgehen. Wie man das an den angehangenden Bildern 
sehen kann. (Hier wird 0x1B1B gesendet)

Vielen Dank für die große Anteilnahme ;)

LG
mvollmer

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


Lesenswert?

M. Vollmer schrieb:
> Und auch am MISO Pin kommen die Daten wie erwartet wieder raus.
> Was mir grade jedoch aufgefallen ist, das die Daten am MISO um einen
> halben Clock früher rausgehen.
Wie können am zurückkommenden MISO die Daten früher anliegen als am 
abgehenden MOSI? Ich bräuchte mal einen Schaltplan, was hier mit MISO 
und MOSI gemeint ist...

: Bearbeitet durch Moderator
von M. V. (mvollmer)


Lesenswert?

Da hab ich mich falsch ausgedrückt. Die Daten kommen nur um einen halben 
Clock nach hinten versetzt raus, bei der nächsten Übertragung. Das ist 
aber richtig. Das liegt an den Flip Flops
Die zurückkommenden Daten können natürlich nicht vor den empfangenden 
Daten gesendet werden.

PIC = Master; CPLD = Slave
MISO = Master In Slave Out
MOSI = Master Out Slave In

LG Marc

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


Lesenswert?

M. Vollmer schrieb:
> Hier wird 0x1B1B gesendet
Gib doch mal das Bit 0 (oder besser ein paar der LSB) auf CPLD-Pins aus. 
Ich würde sagen, der Slave hat hier auch x1B1B zu empfangen.

BTW:
ich handhabe im CPLD den SS ein wenig anders. Weil eh' alles asynchron 
ist, wird die Flanke des SS ausgewertet:
Siehe http://www.lothar-miller.de/s9y/archives/31-SPI-Slave-im-CPLD.html
Das funktioniert auf jeden Fall zigtausend mal weltweit...  ;-)

von M. V. (mvollmer)


Lesenswert?

Hallo,

vielen Dank für all eure Bemühungen zu helfen :) Leider musste ich 
feststellen, das die Ursache des Problems am CPLD lag, welches nicht die 
aktuelle Softwareversion programmiert hatte.(Ich selbst habe das 
Programm für das CPLD nicht geschrieben, sondern lediglich für den PIC 
;)) Es ist wohl einmal bei einem Update was schief gelaufen.

Vielen Dank noch einmal

LG
mvollmer

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.