Datum: 14.05.2008 15:05
Hallo, ich habe folgendes vor: Ich möchte einen Speicher über einen CPLD an einen ATMega128 anschließen. irgendwann soll dann in den CPLD XC95144XL noch was anderes hinein. Dazu benötige ich das Durchschleifen aller Leitungen vom AVR zum SRAM durch den CPLD. Nun arbeite ich gerade daran grundlegend das Speicherinterface im CPLD hinzubekommen. Da der SRAM recht groß ist, habe ich eine entsprechende Bankumschaltung integriert. Leider macht mir das Adresslatch etwas probleme.
-- Adresslatch LATCH : process(RESET, ALE_AVR) begin if RESET = '0' then S_A_SRAM(7 downto 0) <= (others => '0'); elsif falling_edge(ALE_AVR) then S_A_SRAM(7 downto 0) <= AD_AVR; end if; end process; |
Bei der fallenden Flanke soll hier das untere Adressbyte übernommen werden. Leider übernimmt er ab und zu auch schon teilweise das Datenbyte, welches vom AVR gleich nach dem Abschalten des ALE Signales auf die AD Leitungen gelegt wird. Der CPLD schafft es also nicht rechtzeitig alle Adressbits zu speichern. Was kann ich hier tun? Ich habe es bei 4MHz, 8MHz und 16 MHz AVR-Frequenz ausprobiert. Wenn ich ca. 100pF vom ALE-Eingang am CPLD zu GND lege, dann tritt je nach Zimmertemperatur sogar eine langanhaltende Besserung ein (Jedoch am nächsten Tag läuft es wieder nicht). Jetzt noch ein paar Randdaten: - der CPLD läuft mit 3,3V und ist vom Typ 10ns - der AVR läuft mit 5V und ich habe es bei verschiedenen Frequenzen ausprobiert - Die Kabel der AD-Leitungen und ALE-Leitung sind ca. 10cm lang. (von einer Testplatine zur nächsten) Hat jemand vielleicht schon einmal ein Adresslatch im CPLD integriert und ähnliche Probleme gelöst? Vielen dank im Voraus, Netbandit
Datum: 14.05.2008 15:30
mir ist nur eins aufgefallen, Du hast kein Latch sondern ein flankengesteuertes FF gebaut. Gruß Volker
Datum: 14.05.2008 15:35
Das FF ist flankengesteuert, sollte aber trotzdem funktionieren. Mich deucht, dass der ATmega recht anspruchsvoll an dieser Stelle ist, da gibt es n+1 Bits, die richtig gesetzt werden müssen. Atmel schreibt da einige bemerkenswerte Sätze im Manual.
Datum: 14.05.2008 15:43
Ja stimmt, aber auch pegelgesteuert gibt es das gleiche Problem :) Ich bin etwas voran gekommen und hab eine kleine FSM programmiert, welche das untere Adressbyte immer 4 Zyklen nachdem ALE auf 1 gegangen ist, einmalig speichert (und erst wieder wenn ALE zwischenzeitig auf 0 gegangen war). Bis jetzt läuft es auf 8 MHz vom AVR recht gut, den Takt im CPLD brauch ich eh später, es kostet mich eben zusätzlich noch einmal 2 Register und irgendwie kommt mir soetwas leicht Überzogen für solch eine Anwendung vor. Vielleicht hat ja jemand noch eine andere Idee...
LATCH : process(ALE_AVR, CLK) begin if ALE_AVR = '0' then Z_LATCH <= "00"; elsif falling_edge(CLK) then case Z_LATCH is when "11" => S_A_SRAM(7 downto 0) <= AD_AVR; Z_LATCH <= "11"; when others => Z_LATCH <= Z_LATCH + 1; end case; end if; end process LATCH; |
@Banause: Stimmt schon, der AVR scheint etwas anspruchsvoll zu sein, was sein Latch angeht. Im Datenblatt steht leider nur, dass der dem Latch ca. 5ns zum Speichern gibt, nachdem ALE auf 0 gegangen ist. das ist schon recht wenig. Leider habe ich keine Funktion in den Registern gefunden mit der man hier ein besseres Timing einstellen kann, es gibt da eben nur die Wate States und über die kann man das ALE Signal nicht beeinflussen. Also im Datenblatt hab ich dazu noch nichts gefunden oder meinst du ein anderes Dokument?
Datum: 14.05.2008 16:03
Ich meine das dicke Manual; weitere Dokumentation dazu kenne ich erst mal nicht. Wie hast du das Bit XMBK gesetzt (external memory bus keeper)? Das kann Schwierigkeiten im Timing machen! Mein Kollege hatte da mal was - ich weiß es aber nicht mehr genau und kann ihn nicht mehr fragen, da er ausgebüxt ist.
Datum: 14.05.2008 16:09
Das hab ich auf low, da ich denke, dass hochohmige Zustände erstmal nicht so verkehrt sind, wenn der AVR nichts auf dem Bus zu suchen hat.
Datum: 14.05.2008 16:17
Blöd, war so eine Vermutung. Dann hilft nur noch der LA weiter.
Datum: 14.05.2008 16:22
nun ja, 5ns ist ja wirklich nciht viel, schon mal die Flanken vom ALE Signal auf einem Oszi angesehen? Eventuell sind da zu starke Überschwinger drauf. Auch noch wichtig: Bist Du mit dem ALE Signal auf einen dafür vorgesehenen "global Clock" Eingang des CPLDs gegangen? Gruß Volker
Datum: 14.05.2008 17:01
Ja einen LA hab ich nicht, ich kann jedoch das "wackeln" der unteren Adressbits ganz gut mit dem Oszi beobachten. Ist die untere Adresse 0x00 und soll dann ein Byte 0xFF geschrieben werden, so ist es eben durchaus möglich, dass anstatt 0x00 als Adresse 0xFF gespeichert wird. Das ALE Signal war sowohl schon einmal auf einem normalen Pin als auch auf dem CLK Pin, auf dem normalen Pin lief es sogar etwas besser... Es sind zumindest bei 16 MHz gewisse Überschwinger vorhanden, die bekomme ich auch nicht einem kleinen Kondensator weg. Allerdings ist es hier sehr fragwürdig, was das Oszi da anzeigt, denn je nachdem ob das Oszi dransteckt oder nicht läuft es eben besser mit dem ALE oder eben auch nicht. Also beeinflusst das Oszi die Signalform durchaus beträchtlich.
Datum: 14.05.2008 17:09
Da weißt du jetzt, wo der Hund begraben liegt. Ich würde mal noch versuchen, am XC95144 entsprechend harte timing constraints zu setzen. Für 5 ns mit Überschwingern könnte der -10 Typ auch ein wenig zu schlaff sein. Gute Besserung - Banause
Datum: 14.05.2008 17:14
>>Es sind zumindest bei 16 MHz gewisse Überschwinger vorhanden, die >>bekomme ich auch nicht einem kleinen Kondensator weg. Die Überschwinger sollten eigentlich nicht frequenzabhängig sein, da ja nur ein einzelner Schaltvorgang zählt. Versuch mal in alle Leitungen (ALE, und AD) 33 Ohm in Reihe zu schalten und dann noch etwa 33 pF nach Masse. Was passiert, wenn Du das Kabel mit den AD-Signalen verlängerst, das ALE Signal aber bei 10cm belässt, damit sollte eigenlich das Timing besser werden. Gruß Volker
Datum: 14.05.2008 17:19
Du könntest auch mal folgendes machen: Programmier mal einen Counter/Frequenzteiler in den CPLD, der vom ALE-Signal als Clock gespeist wird. Damit könnte man sehen, ob auf ALE solche Überschwinger vorhanden sind, die die "falling Edge" mehrfach auslösen. Gruß Volker
Datum: 14.05.2008 18:08
Wenn Du alle Signale "Durchschleifen" willst, dann evtl. auch den gemultiplexten Bus. Den mit Widerständen (470 Ohm sollte gehen) auf die Signale koppeln. Die XC95... haben soweit ich weiß leider keine eigenen Buskeeper. Bei mir hatte es zumindest so geklappt mit XMBK=0 und latchen der durchgeschleiften Signale. Gruß Jörg
Datum: 14.05.2008 21:31
So, nach einigen Stunden Testzeit scheint diese Mini FSM recht gut zu funktionieren. Es sind nur noch sehr wenige Fehler beim Lesen/Schreiben am SRAM aufgetreten. Die restlichen Fehler liegen vielleicht daran, dass die Bustreiber nach dem abschalten des RD/WR -Signales den Bus entsprechend hochohmig geschaltet haben. Hier habe ich nachdem Vorbild der Latch FSM ebenfalls eine kleiner Verzögerung eingebaut. Seither hatte ich keine Fehler mehr. Da ich im Moment nicht so viel Zeit habe, werde ich es wohl erst einmal dabei belassen, bis ich die entsprechenden Ressourcen im CPLD vielleicht für was anders brauche, bis jetzt reicht es ja noch. Im Moment müsste ich eigentlich besser für Klausuren lernen und wollte "nur mal eben schnell" einige Gedankenblitze in die Tat umsetzen, bevor ich die nächsten Wochen nur noch Taschenrechner und Zahlen sehe :) Ich denke, dass ich in den nächsten Semesterferien ein bisschen mehr zeit finde der Ursache genauer auf den Grund zu gehen, dann werde ich Volkers Vorschläge mal umsetzen und mich deswegen noch einmal melden. Den Vorschlag von Jörg kann ich im Moment nicht ganz nachvollziehen. Der gemuxte Bus wird ja in den CPLD eingebracht und dort dann in einen getrennten Daten und Adressbus geteilt (durch das Latch) daher wird dieser ja schon "durchgeschliffen". Aber vielleicht hab ich es einfach nur falsch verstanden, vielleicht könntest du das ganze noch einmal konkretisieren. Also dann danke ich erst einmal für die Vorschläge und ich werde mich melden, sobald ich mich noch einmal genauer damit beschäftigt habe.
Datum: 15.05.2008 08:54
Das "Durchschleifen" wie ich es beschrieben habe, bewirkt folgendes: Beim Schreiben auf das externe RAM liegen auf dem Datenbus an: Adresse -> undefiniert -> Daten wobei XMBK keinen Einfluss hat. Durch die Laufzeit im CPLD schalten die durchgeschleiften Signale etwas später um. Und gerade diese Zeit gewinnt man beim Adresslatch. Man kann die Verzögerung auch noch etwas erhöhen, indem man die Signale nicht direkt durchschleift, sondern z.B. mit RD UND-verknüpft. Die in meinem oberen Post beschriebenen Widerstände brauchst Du nicht. Das war bei mir damals notwendig zwecks "Hotplugging". Gruß Jörg
Datum: 15.05.2008 09:44
Ja das wäre schon eine Idee, wenn die geänderten Pegel auf dem AD Bus eben später am "Latch" ankommen, dann werden noch die Adressen richtig gespeichert. So wie ich das sehe, ist jedoch die einzige Möglichkeit, soetwas möglichst definiert zu machen mit Hilfe von Timing Constraints... Da müsste ich mich erstmal genauer einarbeiten. Bis jetzt hab ich das Timing von der ISE erledigen lassen :-) Wie würde man so etwas definieren, wenn es ca. 5 bis 10ns später erst am Latch ankommen soll? Es einfach nur durch eine Verknüpfung zu machen scheint mir da etwas risikoreich, je nachdem wie die ISE das ganze in den CPLD programmiert klappt es dann halt mal und mal nicht.
Datum: 15.05.2008 10:13
Blöde Frage, aber haben die beiden eine gemeinsame Masse (CPLD <-> AVR)?
Datum: 15.05.2008 11:09
Datum: 15.05.2008 12:05
Das Problem mit dem ALE eines AVR in Verbindung mit einem FPGA hatte ich anfangs auch. Habe aber gelernt: "Erst lesen, dann machen". Sieht man sich die Timings des AVR an, stellt man fest, dass es nicht einfach ist, auf die fallende Flanke von ALE zu synchronisieren, weil die Adresse schon 5ns danach schon "weg" ist. Man muss erstmal nachsehen, wie lange die Adresse gemeinsam mit dem Signal ALE anliegt, um die Adressen korrekt zu lesen. Die Adresse liegt vor ALE = L für 1/2tclk -5ns am AVR an. Außerdem liegt sie mindestens 5ns nach ALE = L an. Die zusätzlichen 5ns bringen uns zwar nichts für die Berechnung, aber verschafft einige Timingsicherheit. Bei 16MHz also 0.5*62.5ns -5 = 26.25ns. Das sind 38.09MHz. Um also sicher einen Takzyklus des FPGA "in das Zeitfenster hineinzubringen", müsste der Takt zum Sampeln theoretisch mindestens 2.38 mal so hoch sein, wie der Takt des 16MHz-AVR. Etwas zusätzliche Sicherheit kann nicht schaden. Also 40MHz würde ich mindestens nehmen. Mein Aufbau bestand aus 16MHz AVR und 50MHz FPGA, aber wie gesagt 40MHz tuns auch. Eine Abtastrate doppelt so hoch die die AVR-Frequenz REICHT NICHT!! Das Einlesen geht ganz einfach in meinem Fall
process (RESET, CLK) begin if (RESET='0') then -- hier Reset elsif (rising_edge(CLK)) then if ALE = '1' then Global_Address(15 downto 8) <= Address; Global_Address(7 downto 0) <= ADBUS; end if; if WR = '0' then HOST_WR_DATA <= ADBUS; end if; end if; end process; |
Die Information an "ADBUS" wird also immer eingelesen, solange ALE High ist. Dabei ist es egal, ob der FPGA-Takt 40MHz oder 200MHz ist. Es wird eben immer solange eingelesen, bis es sich durch ALE = Low nicht mehr ändert. Nur die Mindesttaktrate ist wichtig, damit in den Bereich, wo die Adressdaten anliegen garantiert eine Abtastflanke fällt. Eine Verwendung der (gelatchten) Adresse "Global_Address" erfolgt ja erst bei Auftreten von WR oder RD, weshalb "zu früh abgetastete" ungültige Adressdaten überhaupt keine Rolle spielen. Bei mir funktioniert das hundertprozentig. Joachim
Datum: 15.05.2008 15:05
Hi Joachim, ja so hatte ich das erst auch mal getestet. Ich habe einen CLK von 66MHz also nach deiner Berechnung völlig ausreichend. leider hat das bei mir nicht funktioniert. Ich hab kein LA, um genau zu prüfen, warum das damit nicht immer funktioniert hat. Ausgehend von dieser Version hab ich dann die FSM getestet, die läuft bei mir bei 8MHz (AVR Takt) 100%ig. Heute Abend will ich meine Timings noch einmal überarbeiten und gucken ob ich wieder auf 16MHz hochschalten kann. Ich denke ein Großteil der Probleme, die ich mir hier damit gemacht habe kommen durch die ca. 10cm langen Leitungen und die damit einhergehenden Kapazitäten. Die Signale, die ich mit dem Oszi messe sind alles anderes als klar und Überschwinger sind an der Tagesordnung. Eine wesentliche Verbesserung verspreche ich mir, wenn ich irgendwann den Testaufbau auf eine Platine bringe und damit die Leitungswege kürzer werden. Vielleicht helfen hier auch kleine Tiefpässe an den Leitungen, wie Volker es vorgeschlagen hat. Interessant ist halt, dass man zu diesem Problem kaum etwas im Internet findet, wobei ich mir vorstellen könnte, dass die Realisierung eines Adresslatches über PLDs und FPGAs für µCs grundsätzlich sehr verbreitet sein wird.
Datum: 15.05.2008 17:19
Naja, wenn es natürlich Störprobleme sind, hilft es auf der Programmseite nicht wirklich weiter. Als ich mal mit Xilinx-CPLDs rumgespielt hatte, machten diese anfangs gar nicht, was ich wollte. Die sind sehr empfindlich bezüglich unsauberem Aufbau, Spannungsversorgung und Masse. Erst auf einer "gescheiten" Platine liefen die einwandfrei. Die "Steckbrettlösung" mit Adapterboard war eine Katastrophe. Jedenfalls programmtechnisch muss es so funktionieren. Anfangs hatte ich auch eine Kombination AVR<>CPLD (Altera). Da hatte ich einfach einen globalen Clockeingang des CPLD an das Signal ALE angeschlossen. Das war natürlich die einfachste Lösung als Anfänger. Aber mit einem FPGA erscheint mir eine vollsynchrone Lösung besser als die asynchrone Lösung unter Verwendung dedizierter Clockpins. Ist sicherer und einfacher auf andere Hardware portierbar. Die Clockpins können einem schnell mal ausgehen, wenn man die allzu großzügig verschwendet. Und da man RD und WR eh auf den Systemtakt synchronisieren muss, macht ein separater Clock durch ALE nur Probleme. Viel Erfolg Joachim
Datum: 16.05.2008 10:12
"- Die Kabel der AD-Leitungen und ALE-Leitung sind ca. 10cm lang. (von einer Testplatine zur nächsten)" Bei einer Hold-Zeit von 5ns kann es durch den "fliegenden" Aufbau und dadurch bedingte kapazitive Last durchaus vorkommen, daß das ALE erst im CPLD ankommt nachdem sich schon einige Adressbits geändert haben! So etwa Knappes funktioniert üblicherweise nur mit so kurz als möglich gehaltenen Leiterbahnen. In der AVR-Doku steht auch noch ein Halbsatz zum Thema Latch vom 74AC-Typ. Einige CPLDs sind hier langsamer - okay, ich kenne den verwendeten CPLD-Typen nicht so gut aber eventuell liegt es schon daran. Ein synchrones Design (mit extra Takt), wie von Joachim vorgeschlagen, würde ich an dieser Stelle lieber nicht machen, da in der AVR-Doku ja schon drinsteht, daß das XRAM-Interface nicht absolut präzise zum AVR-Takt arbeitet - die zetliche Relation kann schwanken. Und dann noch eine zusätzliche Taktquelle die asynchron zum AVR-Takt ist; scheint mir eher das Problem zu verschlimmern. Also ist mein Vorschlag mal das Timing des CPLD (Setup- und besonders Hold-Zeiten der FFs) zu prüfen und nachzuschauen, ob das überhaupt ausreicht. Kann es zusätzlich daran liegen, daß der AVR mit 5V läuft? Das bedingt am CPLD mit 3,3V einen niedrigeren Umschaltpunkt für '1'->'0' und kann daher nochmal etwas Hold-Zeit kosten durch die Zeit für das Abfallen des ALE. Rein prinzipiell hätte ich auch ein pegelgesteuertes äquivalent zum 74xx573 eingebaut. Das ist zwar nicht gerne gesehen (weil voll asynchrones Design) hier aber gerechtfertigt. Die 5ns Nachlauf der Adresse zum ALE werden nicht aus irgendwelchen Takten des AVR gewonnen sondern rein durch fest eingestellte Laufzeitglieder und -effekte. Daher nutzt auch das Ändern der Taktfrequenz rein gar nichts. Gruß H.A.R.R.Y.
Datum: 16.05.2008 15:34
Ja der fliegende Aufbau ist wirklich ein Graus. Dabei hat sowohl der AVR als auch der CPLD eine sehr vernünftige Spannungsversorgung mit allen C's die so an die VCC-Pins heran gehören. Aber die Leitungen eben... Aber was soll man tun? So ein CPLD Design entwirft man nicht mal locker auf einer extra dafür gefertigten Platine. Solange der fertige VHDL Code nicht gefittet wurde, steht ja noch gar nicht fest an welchen Pin welches Signal kommt. Ab einer entsprechend hohen Belegung des CPLD (bei mir der Fall) kann schon das Einfügen eines kleinen logischen Gatters in den VHDL-Code dazu führen, dass etliche Pins umgelegt werden. Hier kann man wohl wirklich nur mit Testplatinen arbeiten, wo man mal eben schnell die Drähte zum CPLD umstecken kann. Mein "syncronlatch" von oben geht zumindest bei 8MHz problemlos. Bei 16MHz kommt es ab und an wieder zu Memoryproblemen, aber hier weiß ich noch nicht, ob das am Latch liegt oder an einer anderen Stelle meines Designs (hab mir diese Fehler noch nicht über ein Oszi ansehen können). Wäre der CPLD etwas größer könnte man bestimmt ein vollsyncrones Design aufbauen, sobald die Signale vom CPLD erstmal richtig "eingetaktet" wurden würde dann alles richtig laufen... aber ich fürchte, dafür reicht der CPLD eben nicht :-)
Datum: 16.05.2008 21:36
Sehr interessant dein Projekt. Schau dir mal diesen Thread an. Beitrag "AVR Ethernet Platine" #define CPLD_MM_ _attribute ((section (".cpldmm"))) #define FTDI_MM_ _attribute ((section (".ftdimm"))) #define USB_MM_ _attribute ((section (".usbmm"))) #define BANK0_ _attribute ((section (".bank0"))) #define BANK1_ _attribute ((section (".bank1"))) im Makefile müssen nun die Addressen zu den obigen Sections stehen: LDFLAGS += -Wl,--section-start=.cpldmm=0x801100 LDFLAGS += -Wl,--section-start=.ftdimm=0x801200 LDFLAGS += -Wl,--section-start=.usbmm=0x801300 LDFLAGS += -Wl,--section-start=.bank0=0x802000 LDFLAGS += -Wl,--section-start=.bank1=0x808000 Der Addressbereich des CPLD's startet also physikalisch an Addresse 0x1100. Im Source kann nun eine Memory-gemappte Variable zu diesem Addressbeeich definiert werden. uint8_t CPLD[256] CPLD_MM; Beim Zugriff auf diese 256 Char Array wird nun physikalisch in die Addressen 0x1100 bis 0x11FF gemappt. Anbei mal mein Memory Mapped Bank Controller zur Ansteuerung von 512Kb SRAM und zwei beliebigen Memory Mapped Geräten. Das ganze passt in einen XC9536XL benötigt alle 34 verfügbaren Pins und verbraucht 27 Makrozellen von den 36 verfügbaren. Da der MMB aber intern selber zwei Register speichert und demzufolge auch die komplette Addresslogic des AVR's benötigt kann für euer Projekt einiges eingespart werden. entity MMB is port( AVR_AD: inout std_logic_vector(7 downto 0); AVR_AH: in std_logic_vector(7 downto 0); AVR_ALE,AVR_RD,AVR_WR: in std_logic; -- A0-A7, A15,A16,A17,A18, CS~ AL: out std_logic_vector(7 downto 0); AH: out std_logic_vector(3 downto 0); CS: out std_logic_vector(2 downto 0) ); end MMB; -- 512Kb SRAM pinning -- CS~ -> CPLD.CS(2) -- WR\ -> AVR.WR\ -- RD\ -> AVR.RD\ -- A0-A7 -> CPLD.AL -- A8-A14 -> AVR.A8-A14 -- A15-A18 -> CPLD.AH -- IO0-IO7 -> AVR.AD0-AD7 -- AVR pinning -- WR\ -> CPLD.AVR_WR\ -- RD\ -> CPLD.AVR_RD\ -- ALE -> CPLD.AVR_ALE -- AD0-AD7 -> CPLD.AVR_AD -- A8-A15 -> CPLD.AVR_AH -- zwei memory mapped devices -- CPLD.CS(0) oder CPLD.CS(1) -- 8 Bit gelatchter Addressraum an CPLD.AL, pro devices also 256 bytes addressraum -- + 4 Bit Addressraum ?ber Bankswitch register 0 zus?tzlich, d.h. durch vorheriges -- schreiben von 4 bits in Bank_Register_0 kann beim sp?teren Zugriff auf die -- memory mapped devives ?ber CPLD.AH der addressbereich manuell auf 12bit erweitert -- werden. Eventuell k?nnen diese 4 bits in CPLD.AH == Bank_Register_0 auch f?r andere -- aufgaben benutzt werden. CPLD.AH enth?lt also je nach Addressleitung A15 entweder den -- vorher gespeicherten Wert aus Bank_Register_0 oder Bank_Register_1. -- ?ber Addressen 0x0500 - 0x05FF kann ?ber jedes Byte das interne Bank_Register -- gelesen oder geschrieben werden -- Bits 0-3 definieren A15-A18 f?r Bank 0 -- Bits 4-7 definieren A15-A18 f?r Bank 1 -- je nach Level auf A15 werden diese Bits auf CPLD.AH ausgegeben -- greift man also auf Addressen kleiner 0x8000 zu so wird CPLD.AH == Bank_Register_0 sein -- ansonsten CPLD.AH == Bank_Register_1 -- im falle das CPLD.CS(2) also aktiv ist und somit der SRAM selektiert wurde bestimmen die -- Werte im Bank_Register die obersten 4 Adressbits f?r den SRAM. Da die Bank_Register frei -- programmierbar sind kann im Speicherbereich von 0x0000-0x7FFF und 0x8000 bis 0xFFFF jede -- beliebige 32Kb SRAM Bank eingeblendet werden, auch doppelt. architecture behavioral of MMB is signal Bank_Register: std_logic_vector(7 downto 0) := (others => '0'); signal AL_Latch: std_logic_vector(7 downto 0) := (others => '0'); signal CS_Latch: std_logic_vector(2 downto 0) := (others => '0'); alias A15: std_logic is AVR_AH(7); alias Bank_0: std_logic_vector(3 downto 0) is Bank_Register(3 downto 0); alias Bank_1: std_logic_vector(3 downto 0) is Bank_Register(7 downto 4); begin process(AVR_ALE, AVR_AD, AVR_AH) begin if AVR_ALE = '1' then AL_Latch <= AVR_AD; -- Chip Select Addressdekodierung, low active -- ATMega162 0x0500 start externer SRAM -- ATMega128 0x1100 start externer SRAM -- hier Addressdekodierung f?r ATMega162 -- Addressbereich Typ AVR_AH CS~ -- 0x0500 bis 0x05FF --- CPLD 0000 0101 111 -- 0x0600 bis 0x06FF CS0 0000 0110 110 externes Device 0 -- 0x0700 bis 0x07FF CS1 0000 0111 101 externes Device 1 -- 0x0800 bis 0xFFFF CS2 SRAM 011 512Kb SRAM CS_Latch <= "011"; if AVR_AH(7 downto 2) = "000001" then case AVR_AH(1 downto 0) is when "01" => CS_Latch <= "111"; when "10" => CS_Latch <= "110"; when "11" => CS_Latch <= "101"; when others => NULL; end case; end if; end if; end process; process(AVR_WR, AVR_RD, AVR_AD, CS_Latch, Bank_Register) begin AVR_AD <= (others => 'Z'); if CS_Latch = "111" then if AVR_WR = '0' then Bank_Register <= AVR_AD; else if AVR_RD = '0' then AVR_AD <= Bank_Register; end if; end if; end if; end process; AL <= AL_Latch; AH <= Bank_0 when A15 = '0' else Bank_1; CS <= CS_Latch; end behavioral;
Datum: 17.05.2008 11:24
> process(AVR_ALE, AVR_AD, AVR_AH) > begin > if AVR_ALE = '1' then > AL_Latch <= AVR_AD;
Datum: 17.05.2008 12:02
Sorry, falsche Taste abgefeuert :-) > process(AVR_ALE, AVR_AD, AVR_AH) > begin > if AVR_ALE = '1' then > AL_Latch <= AVR_AD; Diese Lösung hier entspricht genau dem, was ich ja auch gesagt habe. @netbandit: Also wenn Dein CPLD so voll ist, dass Pins getauscht werden müssen, damit es reinpasst, dann würde ich mir überlegen, ein größeres CPLD zu nehmen. Ich hatte damals mit ISE7 ein XC9572 Design gemacht, welches auch randvoll war. Und da kamen plötzlich Probleme. Obwohl die Software das Design synthetisierte, lief das CPLD fehlerhaft. Entfernte ich nur eine kleine Funktion, so dass eine Makrozelle mehr frei war, lief alles so, wie geplant. Trotz tagelangem Suchen gelang es mir nicht, herauszufinden, was da passiert war. Seitdem trau ich dem Xilinx-Ding nicht mehr und arbeite mit Altera. Da ist mir trotz "Vollpacken bis zum Anschlag" noch nie dergleichen passiert. Benutze Altera MaxII EPM240 oder EPM570. Wenn Du schon mit XC95144 am Ende bist, würde ich mir ein kleines FPGA überlegen. Ein größeres CPLD kostet schon über 10,- Euro und dafür bekommst Du schon ein kleines FPGA, in das viel mehr reinpasst. Gruß Joachim
Datum: 17.05.2008 13:27
@Holger: > process(AVR_ALE, AVR_AD, AVR_AH) > begin > if AVR_ALE = '1' then > AL_Latch <= AVR_AD; > end if; > end process; Ja genau so hatte ich mir das ursprünglich mal vorgestellt... > process(AVR_WR, AVR_RD, AVR_AD, CS_Latch, Bank_Register) > begin > AVR_AD <= (others => 'Z'); > if CS_Latch = "111" then > if AVR_WR = '0' then > Bank_Register <= AVR_AD; > else > if AVR_RD = '0' then > AVR_AD <= Bank_Register; > end if; > end if; > end if; > end process; Und das geht bei mir auch nicht. Ich habe auch hier einen kleinen "Puffer" programmiert, der die Ausgänge nicht sofort umschaltet, nachdem das RD oder WR Signal wieder weg ist, sondern einen der die Ausgänge noch 3 CLK-Perioden länger aufhält. Ansonsten gibt es auch hier bei mir große Probleme, das Datum nicht richtig im Speicher gespeichert oder nicht richtig vom AVR gelesen wurde. (es war dann zu früh weg) Wenn ich mir ansehe, wie trivial so eine Sache bei anderen Projekten funktioniert, denke ich, dass bei mir das grundlegende Problem ein ganz anderes ist. Ich bin schon die ganze zeit am Überlegen, wie ich den Testaufbau besser gestalten kann, aber irgendwie müssen halt die Signal von der AVR Platine zur CPLD Platine und weiter zur SRAM Platine kommen und somit entstehen nun einmal längere Leitungen. Ich ätze mir auf jeden Fall keine Platine, bevor nicht das Design im CPLD steht und ich kann mir nicht vorstellen, das andere Projekte soetwas machen... Holger, wie hast du das denn getestet? Hattest du deine Platine schon vor dir mit festgeschriebener Pinbelegung oder hast du auch einen Testaufbau benutzt? Ich glaube ich reiße alles noch einmal ab und beginn von vorn. Vielleicht setze ich die Testplatinen huckepack, so kann man eventuell die Leitungswege noch einmal erheblich kürzen. @Joachim Naja, das will ich eigentlich aus Prinzip nicht machen :-) Ich baue einen kleinen LCD Controller, welcher ein 320*240 S/W LCD ohne eigenen Controller ansteuert. Soetwas in der Art wurde von Ulrich R. mit einem 9572er erledigt (nur ohne XMEM-Interface, so dass ein lesen das Speichers vom AVR aus nicht möglich war) und von Benedikt, der das mit einer Handvoll Logikbausteinen realisiert, will ich hier gar nicht erst reden. Mir erscheint der 95144 schon leicht zu Overkill für diese Aufgabe... und wenn ich nicht diese ganzen Probleme hätte könnte ich das XMEM-Interface, wie Holger völlig asyncron aufbauen und würde auch wesentlich weniger speicher benötigen - nur der LCD Teil müsste dann getaktet laufen... eine große Ersparnis an Makrozellen! Ich werde noch einmal alles löschen, alle Leitungen abreißen und ganz langsam von vorne beginnen und schauen an welcher Stelle es bei mir hakt. Aber da jetzt die Klausurzeit ansteht hab ich etwas wenig Zeit dafür... also mal sehen, spätestens Ende Juli, wenn alle Klausuren geschrieben sind stürze ich mich noch einmal in das Projekt.
Datum: 18.05.2008 08:43
So, gestern Abend habe ich noch einmal alles abgerissen und neu gemacht. Dabei hab ich die Testplatinen übereinander angeordnet, wodurch ein Kabel von einer Platine zur nächsten nun nur noch 3cm lang ist. Und siehe da: Das Latch arbeitet jetzt völlig asynchron, so wie Holger es vorgeschlagen hat, bzw. wie ich es im Eingangspost beschrieben hatte. Auch der IO Buffer für die Tristateausgänge kann gleichzeitig mit RD/WR schalten. Der AVR kann nun wieder mit 16MHz und völlig ohne Wait-States auf den Speicher zugreifen. Also es hat alles nur an der Leitungslänge gelegen... hätte ich nicht gedacht. Leider hat gestern die Zeit nicht mehr ausgereicht um noch die VHDL Routine zu integrieren, welche den Speicherinhalt wieder ausliest und an das LCD schickt. Aber das sind jetzt auch nur noch wenige Zeilen VHDL und die passen schon noch rein. Ich hab mal ein Bild vom Aufbau angehangen und wenn alles gut geht kann ich ja heute Abend mal ein Bild vom funktionstüchtigen LCD reinstellen. Ganz oben ist die Testplatine mit dem AVR, da drunter die mit dem CPLD und ganz unten ist die Testplatine mit dem SRAM. Also dann noch einmal danke für eure Tips, und dass ich mich ein wenig ausheulen konnte :-) Bis dann, Netbandit
Datum: 25.05.2008 00:28
So, es hat noch einmal ne ganze Weile gedauert, bis ich fertig wurde. Gerade dann wenn der CPLD sich langsam füllt, fängt er an sehr ungünstig zu routen, wodurch es leicht zu Timingproblemen kommen kann. Nachdem ich jetzt alles hinter dem Latch vollsynchron aufgebaut habe läuft es aber. Wie versprochen gibt es dazu auch ein Bild. Natürlich gibt es noch viel Verbesserungsbedarf, vielleicht kann ich die Zahl der Functionblocks noch etwas reduzieren und die Timings noch etwas straffen (sind bisher recht großzügig ausgelegt, aber ein 15ns SRAM gibt halt auch etwas mehr her). Aber mit diesen ganzen Verbesserungen werde ich mich nach der Klausurzeit genauer beschäftigen, jetzt bin ich erst einmal froh über meinen eigenen LCD-Controller. Also dann bis zu meinem nächsten Problem ;) Ciao, Netbandit
Antwort schreiben
Die Angabe einer Email-Adresse ist freiwillig. Wenn Sie automatisch per Email über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.
Wichtige Regeln - erst lesen, dann posten!
- Suchfunktion und Betreffsuche benutzen - vielleicht gibt es schon einen ähnlichen Beitrag
- Aussagekräftigen Betreff wählen
- Im Betreff angeben um welchen Controllertyp es geht (AVR, PIC, ...)
- Groß- und Kleinschreibung verwenden
- Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
- JPEG-Dateien (.jpg) nur für Fotos und Scans verwenden
- Schaltpläne, Screenshots usw. als PNG oder GIF anhängen
Formatierung (mehr Informationen...)
- [c]C-Code[/c]
- [avrasm]AVR-Assembler-Code[/avrasm]
- [vhdl]VHDL-Code[/vhdl]
- [pre]vorformatierter Text (z.B. Code in anderen Sprachen)[/pre]
- [math]Formel in LaTeX-Syntax[/math]
- [[Titel]] - Link zu Artikel

