Forum: FPGA, VHDL & Co. 16bit Übergabe von uC zu CPLD


von Full W. (realjey)


Angehängte Dateien:

Lesenswert?

Hallo Mikro-Freaks,

Ich habe wie im Anhang zu sehen einen uC(PIC18F4520) über portd (8bit) 
mit einem CPLD(XC95288XL) verbunden.
Da ich 16bit-Register im CPLD mit diesen Daten füllen möchte ist nun 
mein Plan diesen 8bit-Datenbus auf "virtuelle" 16bit zu erweitern (zmd. 
in uC->CPLD -Richtung). Hierfür lege ich erst eine 8bit-Adresse auf den 
Datenbus (adressCPLD=1 und chip select=1) und nachfolgend 8bit (lower 
byte oder higher byte)(nur chip select=1).

Also folgende Reihenfolge (PIC):

1- Sende Adresse1
2- sende 8bit (lower byte)
3- sende Adresse2
4- sende 8bit (higher byte)

Mein PIC-Programm sieht folgendermaßen aus:
1
{
2
void Write_CPLD8(char para, unsigned int adress)
3
4
  ////////
5
  //first adress then byte
6
  ////////
7
8
  //send adress
9
  trisd=0x0;              //portd=output
10
  portd=adress;           //8bit-adress on db
11
  portb.2=1;              //adressCPLD=1
12
  portc.0=0;              //CS=1
13
  delay_us(10);           //delay
14
  portc.0=1;              //CS=0
15
  portb.2=0;              //adressCPLD=0;
16
  trisd=0xff;             //portd=input
17
18
  //send lower/higher byte
19
  trisd=0x0;              //portd=output
20
  portd=para;             //byte on db
21
  portc.0=0;              //CS=1, adressCPLD=0
22
  portc.0=1;              //CS=0
23
  delay_us(10);
24
  trisd=0xff;             //portd=input
25
26
  return;     
27
}

Die Funktion wird also 2x für ein vollständiges Datenpaket aufgerufen.

Mein CPLD-Code ist noch in Abel geschrieben (musste leider auf einem 
alten Projekt aufbauen), ich hoffe es gibt noch alte Hasen die damit 
klarkommen:)
1
--chip_select synchronisation
2
Qhelp.Clk=clock;
3
Qhelp0.D=!CS;
4
Qhelp1.D=Qhelp0;
5
CS_pulse=Qhelp0 & !Qhelp1;
6
7
frame[15..0].Clk=clock;
8
9
--adress indication
10
adress[7..0].Clk=clock;
11
adressCPLD_pulse.clk=clock;
12
adressCPLD_pulse=strobe_pulse & adressCPLD;
13
14
--byte indication
15
byte_temp.clk=clock;
16
byteCPLD_pulse.clk=clock;
17
byteCPLD_pulse=(strobe_pulse & !adressCPLD);
18
19
--adresse einlesen
20
when(adressCPLD_pulse == 1) then adress[7..0]:=[DB7,DB6,DB5,DB4,DB3,DB2,DB1,DB0];
21
  else adress[7..0]:=adress[7..0].FB;
22
23
--byte einlesen
24
when(byteCPLD_pulse==1) then byte_temp[7..0]:=[DB7,DB6,DB5,DB4,DB3,DB2,DB1,DB0];
25
  else byte_temp[7..0]:=byte_temp[7..0].FB;
26
27
--framerate choice (lower, higher 8 bit)
28
when(adress[7..0]==[1,1,1,1,1,1,1,1]) then frame[7..0]:=byte_temp[7..0]; 
29
  else frame[7..0]:=frame[7..0].FB;
30
when(adress[7..0]==[1,1,1,1,1,1,1,0]) then frame[15..8]:=byte_temp[7..0]; 
31
  else frame[15..8]:=frame[15..8].FB;

Das ganze scheint eig. auch einwandfrei zu funktionieren, allerdings 
habe ich immer mal wieder Probleme bei der Übergabe. Die Framerate geht 
dann kurzfristig auf 0 und erst danach auf den korrekten von mir 
übergebenen Wert, dies geschieht ca. bei jeder 5. Übergabe. Ich sehe das 
Problem darin, das bei den Zeilen
1
when(adress[7..0]==[1,1,1,1,1,1,1,1]) then frame[7..0]:=byte_temp[7..0]; 
2
  else frame[7..0]:=frame[7..0].FB;
3
when(adress[7..0]==[1,1,1,1,1,1,1,0]) then frame[15..8]:=byte_temp[7..0]; 
4
  else frame[15..8]:=frame[15..8].FB;

teils schon die Adresse erkannt wird aber noch keine byte-Daten auf dem 
Datenbus liegen und er dadurch eine 0 einliest. Beim nächsten Durchlauf 
liegen dann die Daten korrekt in byte_temp und er nimmt den Wert an.

Leider stehe ich gerade ein auf dem Schlauch wie ich hier eine korekte 
Erkennung der Daten implementieren kann. Wäre nett wenn sich das mal 
kurz jemand anschaut.

DANKE!
jey

von W.S. (Gast)


Lesenswert?

Wozu brauchst du denn 8 Bit Adressen? Dein CPLD enthält doch nicht 
einmal annähernd so viele MC wie du damit adressieren kannst.
Ich würde schlichtweg 2 Clocksignale nehmen: mit dem einen stopfst du 
ein Byte in dein CPLD und mit dem anderen das andere Byte. Ferticht.

W.S.

von bko (Gast)


Lesenswert?

Was passiert denn genau, evtl. sowas?

> Jey Soon schrieb:
>Also folgende Reihenfolge (PIC): | frame[15:8] [7:0]
------------------------------------------------------
>1- Sende Adresse1                |    alt       alt
>2- sende 8bit (lower byte)       |    alt       neu
>3- sende Adresse2                |    alt       neu
>4- sende 8bit (higher byte)      |    neu       neu

Beispiel
  PIC                 |  frame[15:8] [7:0]
-------------------------------------------
1- Adresse1           |    0x00   0xFF  <-- alter frame
2- low-byte neu 0x00  |    0x00   0x00  <-- autsch
3- Adresse2           |    0x00   0x00 <-- autsch
4- high-byte neu 0x01 |    0x01   0x00 <-- neuer frame

von Full W. (realjey)


Lesenswert?

W.S. schrieb:
> Wozu brauchst du denn 8 Bit Adressen? Dein CPLD enthält doch nicht
> einmal annähernd so viele MC wie du damit adressieren kannst.
> Ich würde schlichtweg 2 Clocksignale nehmen: mit dem einen stopfst du
> ein Byte in dein CPLD und mit dem anderen das andere Byte. Ferticht.
>
> W.S.

Richtig es werden wahrscheinlich max. 10 Adressen werden, allerdings 
muss ich ja dem CPLD mitteilen welches Register gerade gefüllt werden 
soll.
Wie meinst du das genau mit 2 Clocksignalen?

bko schrieb:
> Was passiert denn genau, evtl. sowas?
>
>> Jey Soon schrieb:
>>Also folgende Reihenfolge (PIC): | frame[15:8] [7:0]
> ------------------------------------------------------
>>1- Sende Adresse1                |    alt       alt
>>2- sende 8bit (lower byte)       |    alt       neu
>>3- sende Adresse2                |    alt       neu
>>4- sende 8bit (higher byte)      |    neu       neu
>
> Beispiel
>   PIC                 |  frame[15:8] [7:0]
> -------------------------------------------
> 1- Adresse1           |    0x00   0xFF  <-- alter frame
> 2- low-byte neu 0x00  |    0x00   0x00  <-- autsch
> 3- Adresse2           |    0x00   0x00 <-- autsch
> 4- high-byte neu 0x01 |    0x01   0x00 <-- neuer frame

genau das scheint zu passieren :/

von Klaus F. (kfalser)


Lesenswert?

when(adress[7..0]==[1,1,1,1,1,1,1,1]) then frame[7..0]:=byte_temp[7..0];
  else frame[7..0]:=frame[7..0].FB;
when(adress[7..0]==[1,1,1,1,1,1,1,0]) then 
frame[15..8]:=byte_temp[7..0];
  else frame[15..8]:=frame[15..8].FB;

Du darfst die Frame-Daten nur übernehmen, wenn CS high ist !

when(adress[7..0]==[1,1,1,1,1,1,1,1] & CS == 1 & AddrCPL == 0) then 
frame[7..0] := DB[7..0];

oder so ähnlich

von Full W. (realjey)


Lesenswert?

Genau so habe ich es mir auch gedacht, allerdings scheint Abel die 
Syntax zwar zu akzeptieren, allerdings führt der CPLD die 
UND-Verknüpfung nicht richtig aus, es werden gar keine Daten mehr in 
Frame geschrieben, da
1
when(adress[7..0]==[1,1,1,1,1,1,1,1] & byteCPLD_pulse==1) then frame[7..0]:=byte_temp[7..0]; 
2
  else frame[7..0]:=frame[7..0].FB;

nie erfüllt ist.

Wenn jemand weiss wie ich in Abel korrekt ein Register und ein Bit in 
einer when-Anweisung als zwei Bedingungen miteinander verknüpfe wäre das 
super, ich denke damit wäre das Problem erledigt (hoffe ich^^)

von bko (Gast)


Lesenswert?

wenn tatsächlich dies passiert:
> Beispiel
>   PIC                 |  frame[15:8] [7:0]
> -------------------------------------------
> 1- Adresse1           |    0x00   0xFF  <-- alter frame
> 2- low-byte neu 0x00  |    0x00   0x00  <-- autsch
> 3- Adresse2           |    0x00   0x00 <-- autsch
> 4- high-byte neu 0x01 |    0x01   0x00 <-- neuer frame

d.h. also wenn die frame [15:0] gleichzeitig anliegen
müssen, dann braucht du noch einen weiteren Zwischenspeicher
für das low-byte:
ich kann kein Abel aber evtl. müsste es so aussehen:
1
when(adress[7..0]==[1,1,1,1,1,1,1,1]) then temp2[7..0]:=byte_temp[7..0]; 
2
  else temp2[7..0]:=temp2[7..0].FB;
3
when(adress[7..0]==[1,1,1,1,1,1,1,0]) 
4
               then frame[15..0]:=[byte_temp[7..0],temp2[7:0]]; --syntax?
5
               -- gebe erstes Byte erst aus wenn zweites auch da   
6
  else frame[15..0]:=frame[15..0].FB;

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.