Hallo zusammen, ich beschreibe mal um was es geht: Ich habe ein kleines Board gebaut, auf dem ein Atxmega, ein FPGA und ein externes SRAM verbaut sind. Das ganze soll ein speichergekoppeltes System werden. Das SRAM wird also für den gemeinsamen Datenaustausch verwendet. Ziel ist es nun, im FPGA einen Memory Controller zu implementieren, der aus dem SRAM ein Dual Port Ram macht. Bei einer Kollision wird gar nicht auf das RAM geschrieben und es wird ein error ausgegeben. Ich will das Ganze verwenden, um mich einzuarbeiten in VHDL. Also brauche ich keinen fertigen Code. Es geht auch nicht um den Zustandsautomat, der die Signale (CE, OE, WE) für das SRAM erzeugt. Das kommt alles später noch. Da muss ich Schritt für Schritt ran. Das Projekt habe ich euch mit angehängt und auch ein Blockschaltbild wie das funktionieren soll. Ich habe versucht die Daten und die Steuersignale voneinander zu trennen. Die Daten vom uC kommen wie aus den Timings (wie angehängt). Da werden alle Signale in Hardware schon erzeugt. Im Block "Datenlatch" werden die Daten auf den SRAM_DATEN-Bus und den SRAM_ADDRESS-Bus verteilt (auf die internen Signale). Über den Block "Steuerwerk" werden die Steuersignale zum SRAM weiter geleitet. Die direkten Signale zum SRAM werden dabei aus den diskreten Signalen von uC und FPGA generiert. Einfach über eine Look-Up Tabelle (die habe ich in Excel für alle Kombinationen erstellt). In erster Näherung betrachte ich nur die Daten vom uC. Daten aus dem FPGA kommen auch erst später. Ich habe für alle Blöcke eigenen Testbenches erstellt und durchlaufen lassen. Die laufen soweit auch. Wenn ich nun aber alles testen will (main), dann geht es aber nicht. Die Daten für die SRAM-Addresse kann ich nicht vorgeben. Ich habe keine Idee woran das liegt. In ISim bleibt das Signal "U". Also undefiniert. Sind die Signalzuweisungen vielleicht nicht richtig? Habe ich irgendwo einen Dreher drin? Vielleicht findet jemand von euch was auffälliges. Vielen Dank euch allen! Grüße, Jens
Jens W. schrieb: > In ISim bleibt das Signal "U". Also undefiniert. Sieh nochmal nach: das 'U' bedeutet 'uninitialized' und das wiederum bedeutet dass dem Signal nie ein Wert zugewiesen wurde. Leider kann mein Handy nichts mit der rar-Datei anfangen...
Hallo Lothar, ja, das ist mir bekannt. In der Testbench steht das:
1 | -- insert stimulus here
|
2 | uC_n_CE <= '0'; |
3 | wait for 15ns; |
4 | |
5 | uC_Data_Address <= "00000001"; |
6 | wait for 15ns; |
7 | uC_ALE_2 <= '1'; |
8 | wait for 15ns; |
9 | uC_ALE_2 <= '0'; |
10 | wait for 15ns; |
11 | |
12 | uC_Data_Address <= "00000011"; |
13 | wait for 15ns; |
14 | uC_ALE_1 <= '1'; |
15 | wait for 15ns; |
16 | uC_ALE_1 <= '0'; |
17 | wait for 15ns; |
18 | |
19 | uC_Data_Address <= "10100101"; |
20 | wait for 15ns; |
21 | uC_n_WE <= '0'; |
22 | wait for 15ns; |
23 | uC_n_WE <= '1'; |
24 | wait for 15ns; |
25 | |
26 | uC_n_CE <= '1'; |
Und um das Signal von uC_Data_Address geht es. Ich weise den Wert direkt zu und trotzdem wird das nicht übernommen. Aber nur für die Addresse. Die dritte Zuweisung für die Daten funktioniert. Das verstehe ich nicht! Grüße, Jens
Vielleicht sollte man morgen nochmal in aller Frische drüber schauen. Ist ja schon spät. Ich bin mir sicher, dass das irgend ein dämlicher Anfängerfehler ist! Trotzdem schonmal danke Lothar! Grüße, Jens
Schau dir mal das synthesereport file (*.syr) an (habs aus dem archive hier angehangen). Da sind IMHO zuviele Signale sourceless (ohne Treiber), interne Tristates sind auch ein Indiz für gering durchdachte Hardware etc.. Da lohnt sich ein Aufräumen sicher. Das Pining sollte man sich auch frühzeitig anschauen (ist als Excel-screenshot auch dabei). Hier sollte immer darauf geachtete werden, das alle Signale die FF in den Pad's nutzen. (begründetet Einzelausnahmen kann es natürlich auch geben). Das scheint bei dir beim Datenbus etc noch nicht der fall zu sein. Das kann dann im Real life zu Problemen führen, die in der Verhaltens-simu untentdeckt bleiben. Auf die schnelle würde ich derzeit auf ein Problem mit Clock/Reset in der Testbench tippen.
Hallo, danke für den Hinweis. Ist das aber nicht so, weil ich das so vorgebe? Das sind ja die Signale, die ans SRAM gehen. Die sind als "inout" definiert. Und solange ich die nicht brauche schalte ich die in tristate, damit nichts passiert. Dann ist es egal, ob das SRAM was auf den Bus legt oder nicht. Die Treiber vom FPGA gehen nicht kaputt. Ich habe ein Bild vom konkreten Problem angehängt. Es geht um das Signal "uC_Data_Address(7 downto 0)". Das ist der Bus, der zum Mikrocontroller geht. Da werden die Adresse und die Daten vom uC an das FPGA übergeben. Die Adresse wird über zwei Latches gespeichert. Der Latch-Enable ist hier "uC_ALE_1" und "uC_ALE_2". Der Code aus der Testbench ist oben schon gepostet. Was ich nicht verstehe ist, dass bei der Übergabe der Adresse das Signal auf "undefined" bleibt (rote Kreise). Dieses "undefined" wird richtig an die SRAM-Adresse übergeben (auch rote Kreise). Wenn ich die Daten auf diesen Bus lege funktioniert es und die werden richtig an das SRAM übergeben. Das ist der gleiche Bus/das gleiche Signal. Warum kann ich einmal keine Daten da drauf legen und einmal schon? Das hat doch mit dem Ausgangstreiber erstmal nichts zu tun, oder? Das Signal "SRAM_Address_Bus(18 downto 0)" ist als "out" definiert und "SRAM_Data_Bus(7 downto 0) als "inout". Kann das damit zu tun haben? Grüße, Jens
Ich sehe gerade, dass die Daten, die ans SRAM gehen sollen, nicht auf den Bus gelegt werden. Da geht das Signal von "Z" auf "U". Also doch irgendwas mit der Verdrahtung. Das muss ein trivialer Anfängerfehler sein, aber ich finde ihn nicht...
Jens W. schrieb: > Das muss ein trivialer Anfängerfehler sein, aber ich finde ihn nicht... Wenn man versehentlich zwei Eingänge miteinander verbindet, dann passiert nämlich genau das. Die Synthese schmeißt die Signale dann (mit Warnung) auch raus. Verbindet man zwei Ausgänge miteinander, bekommt man X in der Simulation. Ich würde spontan mal sagen: "Prüfe alle Richtungen aller Signale" und "Synthetisiere mal durch und untersuche sämtliche Warnungen". Hab mir deinen Code aber nicht angeschaut, daher nur ins Blaue geraten.
Hallo, das Datalatch geht mit seinem Ausgang auf ein internes Signal. Und das interne Signal verwende ich am Eingang von Data_Selector. Liegt das daran? Darf man das nicht machen? Die Signale sind alle im main (Top Entity) miteinander verschalten. In main mache ich also nur noch die Verschaltung der Signale. Die Funktionalität findet in den einzelnen Unterblöcken statt. So war zumindest die Idee. Gruß, Jens
Hallo an alle, also ich glaube ich weiß wo der Fehler liegt. Ich habe nochmal das Grundlagenbuch zu Rate gezogen. Es scheint so zu sein, dass es tatsächlich an dem internen Signal liegt. Signale dürfen nicht dazu verwendet werden um zwischen Entities Daten auszutauschen. So verwende ich es aber im Moment. Ich habe das so wie im Blockschaltbild gemacht. Der Ausgang von "DatenLatch" geht auf ein Signal und das ist wiederum der Eingang von "DataSelector". Das ist aber verboten. Da wird kein Fehler ausgegeben beim Synthetisieren. Aber gut. Das ist halt so. Jetzt habe ich auch gelesen, dass man das als buffer machen könnte, aber das ist wohl verpönt. Das könnte wieder andere Probleme geben. Auch inout wird hin und wieder bemängelt. Man soll wohl die Daten eindeutig auf in und out definieren für einen eindeutigen Signalfluss. Würde einer von euch mir helfen mein Blockschaltbild soweit auf Stand zu bringen, dass es diesen "allgemeinen" Designregeln genügt. Dann kann ich die einzelnen Blöcke überarbeiten und das Ganze wieder zusammen fassen. Für mich ist es sehr schwer, das Denken umzustellen in VHDL. Wenn man aus der reinen µC Programmierung kommt, dann ist das doch sehr anders. War das bei euch auch so? Danke euch! Grüße, Jens
Jens W. schrieb: > Signale dürfen nicht dazu verwendet werden um zwischen Entities Daten > auszutauschen. So verwende ich es aber im Moment. Ich habe das so wie im > Blockschaltbild gemacht. Der Ausgang von "DatenLatch" geht auf ein > Signal und das ist wiederum der Eingang von "DataSelector". Das ist aber > verboten. Wo hast du denn das gelesen?
Jens W. schrieb: > Signale dürfen nicht dazu verwendet werden um zwischen Entities Daten > auszutauschen. So verwende ich es aber im Moment. Genau dafür verwendet man die aber. Des einen Ausgang wird mit des anderen Eingang über ein Signal verbunden... Wie gesagt, ich würde darauf tippen, dass du in deiner Entity-Deklaration (also den Port-Definitionen) einen Richtungsfehler drin hast, und im Top zwei Eingänge miteinander verbunden sind. Mit inout habe ich noch nicht gearbeitet, aber man sollte die ausschließlich für die Pins benutzen, aber nicht zwischen Entities.
Hallo, das habe ich aus dem Buch "VHDL-Synthese" von Reichardt und Schwarz (5. Auflage). Das dürfte geläufig sein. Das kennt sicher der eine oder andere. Steht auf Seite 10. Ja das stimmt schon so, wie ich es geschrieben habe. Man darf Signale nicht verwenden um zwischen Entities Daten auszutauschen. Man darf die nur innerhalb einer architecture verwenden um Blöcke und Funktionselementen zu verbinden. Aber das war auch nicht das Problem. Ich befinde mich in meiner main ja innerhalb einer architcture. Also darf ich die lokalen Signale so verwenden. Das Problem war, dass ich in Modul "DataLatch" einen else-Zweig nicht definiert habe, wo die Adressen eingelatched werden. Das habe ich ergänzt und schon funktioniert auch die Testbench. Trotzdem vielen Dank an alle! Grüße, Jens
Jens W. schrieb: > Ja das stimmt schon so, wie ich es geschrieben habe. Man darf Signale > nicht verwenden um zwischen Entities Daten auszutauschen. Man darf die > nur innerhalb einer architecture verwenden um Blöcke und > Funktionselementen zu verbinden. Na wenn du das sagst, dann wird das schon so sein. Offenbar weisst du da mehr, als wir.
Schlumpf schrieb: > Na wenn du das sagst, dann wird das schon so sein. Naja, streng genommen hat er schon Recht. Signale existieren nur innerhalb einer Entity. Die Verbindungen zwischen Entities sind natürlich auch Signale, aber durch die Hierarchie in VHDL müssen sie immer auch innerhalb einer größeren Entity definiert sein. Ist aber eher esoterisch-akademisch.
Hallo, ja. Aber das war ja auch nicht das Problem. Da habe ich mich vertan. Ich dachte, dass es an den Signalen liegt. War aber nicht. Viel schlimmer war, dass ich bei einer bedingten Zuweisung den else-Pfad nicht definiert hatte. Das habe ich ausgebessert und schon lief es. Dann waren noch zwei Kleinigkeiten drin. Einmal eine zusätzliche Verzögerung von zwei Signalen die ich weg optimiert habe und zum Zweiten waren die Bedingungen für read_write vertauscht. Also ging das Schreiben zum SRAM-Bus nicht. Ich habe noch nicht alles getestet. Es könnten also noch weitere Kleinigkeiten drin sein. Ich hätte eine weitere Frage: Kann man das Ganze nun so kapseln, dass ich das in neune Designs ganz leicht als Block rein nehmen kann? Also als ein komplettes Modul/Lib oder so etwas? Ich möchte ja eigentlich Berechnungen im FPGA machen. Und wenn ich den SRAM-Zugriff nun immer so wie oben mit den verschiedenen Blöcken wie im Blockschaltbild rein nehmen muss, dann wird das Design unübersichtlicher. Das hätte ich gerne überschaubarer gelöst. Oder ist das unüblich? Gruß, Jens
Du kannst einen "IP-Block" draus machen. Damit hab ich aber keine Erfahrung, und ob sich der Aufwand lohnt, kann ich nicht einschätzen. Wenn du dein Interface sauber definiert hast, dann kannst du aber auch einfach die VHDL-Datei in das neue Projekt kopieren, im Top verdrahten und gut ist.
S. R. schrieb: > Naja, streng genommen hat er schon Recht. Wenn man es wirklich ganz genau nimmt, dann existieren Signale nur innerhalb einer Component, welche aus Entity und Architecture besteht. Components kann man in der Architecture einer übergeordneten Component mittels Signale verbinden. Aber wie du schon sagst, dann wird es akademisch-esotherisch oder einfach korinthenkackerisch :) Aber die Schlüsse, die der TO aus dem Buch zog, waren einfach falsch. Und darum ging es. Aber wenn er den tatsächlichen Fehler gefunden hat, ist es ja gut. @Jens: Dein Design ist bereits eine Comonent, die du innerhalb deines übergeordneten Designs beliebig oft instanziieren kannst. Um sie in ganz anderen Designs zu nutzen, kannst du sie entweder in dein Design kopieren und dann dort wieder instanziieren oder eine Library mit der Component erzeugen, die du dann einbinden kannst und dann Instanzen davon erzeugen kannst. Wie das genau geht, findest du bestimmt mit den genannten Begriffen in dem Buch.
Jens W. schrieb: > Ziel ist es nun, im FPGA einen Memory Controller zu implementieren, der > aus dem SRAM ein Dual Port Ram macht. Bei einer Kollision wird gar nicht > auf das RAM geschrieben und es wird ein error ausgegeben. Ich hatte das vor ein paar Jahren mal für eine PAL-Grafikkarte gebaut. War aber dann kein Dual-Port-RAM, sondern ein "Cycle-Shared-RAM". Es gab zwei parallele Busse @ 15MHz und eine Statemaschine hat abwechselnd beide Busse auf ein SRAM (quasi) gelegt, das dann mit 60MHz betrieben wurde. Beide Busse liefen komplett unabhängig und Kollisionen konnte es so keine geben.
:
Bearbeitet durch User
@Schlumpf: Ja du hast Recht: Die Schlüsse, die ich gezogen hatte, waren nicht richtig. Die Aussagen stimmen nur für sich, aber nicht im Gesamten. (Der Fehler war ja auch wo anders) Ich versuche das mal mit einer Library zu kapseln. Das hört sich so an als sei es das was ich mir vorstelle. Danke dir! Grüße, Jens
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.