Moin Hab im SoPC Builder von Quartus leider nur SRAM Controller mit 32 Bits, auf dem DE2 Board sitzt aber einer mit 16 Bits. Nun will ich die Sache so verdrahten, dass die oberen 16 Bits in's Leere gehen (ich weis, nicht besonders sauber, aber egal). Die SoPC Komponente hat nun einen Eintrag ala signal data_to_and_from_the_sram : INOUT STD_LOGIC_VECTOR (31 DOWNTO 0); und mein DRAM SRAM_DQ : inout std_logic_vector(15 downto 0); Frage: Wie verdrahte ich das? Wäre es nur in oder nur out würde ich nicht fragen, aber wie geht das mit inout?
Gast
#1012327
Da wird das Synthesetool auch denken "nicht sauber" und dir massig warnings um die Ohren hauen. Soweit ich weiß müsste es reichen, die unteren 16 Bits zu verbinden und zu den oberen 16 Bits tatsächlich gar nichts weiter anzugeben. Rein formal (und in der Sim) schreibt der Core dann Z-Werte da rein und liest sie wieder aus. In der Synthese wird es Warnings geben, dass du die Signale zuweist aber nie verwendest. Wenn das Synthesetool gut genug ist, dann optimiert es die oberen Signale weg (gibt ja auf den allerwenigsten Chips on-Chip Tristate Buffer) und gut is. Wenn das Tool schlecht ist, dann bricht es ab weil es nicht mehr weiter weiß, aber das ist auf jeden Fall mal nen Versuch wert. Ansonsten baust du halt einen Fake-Verbraucher für die oberen Signale ein, z.B. ein 16er OR Gate, dessen Ergebnis du irgendwo abfragst, damit das Tool zufrieden ist.
Mir ging es eher um die Syntax. Hab ergoogelt, dass es mit Signalnamen im port map funktioniert, also etwa CPU0 : nios2 port map ( ..., data_to_and_from_the_sram(15 downto 0)=>DRAM_DQ); Aber geht das auch ohne Namen? Irgendwie muss es da ja eigentlich eine elegante Möglichkeit geben, man hat ja nicht immer eine extra Komponente. Wenn ich zB. 2 inout signale a und b mit unterschiedlichen Dimensionen hab, und nur a(0) und b(0) direkt miteinander verbinden will, muss das ja auch gehen. Bei einem in und einem out Signal ginge ja einfach a(0) <= b(0), aber das geht ja bei inout nicht. In der Praxis hat das übrigens funktioniert, die oberen Bits waren auf ffff festgenagelt, die unteren haben ihre Daten behalten. Ich glaub Quartus zieht nicht benutzte Signale in der Standardeinstellung auf 1. Ob da nochmal Warnungen gekommen sind weis ich nicht, der haut mir eh schon 400+ um die Ohren, weil ich zB. keine Lastkapazitäten an den Pins angegeben hab, die er aber für eine exakte Timing-Analyse braucht.
Morin wrote: > Da wird das Synthesetool auch denken "nicht sauber" und dir massig > warnings um die Ohren hauen. > > Ansonsten baust du halt einen Fake-Verbraucher für die oberen Signale > ein, z.B. ein 16er OR Gate, dessen Ergebnis du irgendwo abfragst, damit > das Tool zufrieden ist. Warnungen machen doch nichts, wenn der, der vor'm Computer sitzt sie mal durchschaut und befindet, dass alles okay ist. Stell mir grad vor, wie lustig das wäre, wenn ich einen extra-Pin am FPGA hätte, bei dem das Ergebnis vom OR aus kA wieviel nutzlosen Signalen herausgeführt werden würde, weil das Synthesewerkzeug das sonst wegoptimieren würde und das Ganze nur, damit Warnungen nicht ausgegeben werden ... vielleicht kann man da ja ein XOR bauen und eine LED anschließen Grins MfG Thomas Pototschnig
Gast
#1012444
Und was macht der NIOS II, der denkt, dass er einen 32-Bit-Speicher hat? Die oberen 16 Bit werden wohl nicht ganz nutzlos sein.
Sinnvollerweise hängt man noch einen anderen Speicher dran (8MB SDRAM), der volle 32 Bit breit ist und in dem dann libc und code landen. Mir ging es nur mal um die Geschwindigkeit der verschiedenen Speicher. Der SDRAM hat 10MB/s geschafft, der SRAM 16MB/s (trotz nur 16bit). Onboard Speicher war genauso schnell wie SRAM, nur eben 32Bit breit und daher 32MB/s.
Gast
#1013516
> Warnungen machen doch nichts, wenn der, der vor'm Computer sitzt sie mal > durchschaut und befindet, dass alles okay ist. > > Stell mir grad vor, wie lustig das wäre, wenn ich einen extra-Pin am > FPGA hätte, bei dem das Ergebnis vom OR aus kA wieviel nutzlosen > Signalen herausgeführt werden würde, weil das Synthesewerkzeug das sonst > wegoptimieren würde und das Ganze nur, damit Warnungen nicht ausgegeben > werden Du hast das nicht ganz richtig verstanden. Das mit dem Riesen-OR war als Notlösung gedacht falls das Synthesetool nicht nur Warnungen ausgibt, sondern abbricht wegen "geht nicht". Und ja, ich traue diesen Tools inzwischen alles in der Richtung zu. Habe z.B. schon erlebt, wie das XST ungefragt an der Schaltung rum-"optimiert" hat und nachher seine eigenen Änderungen mit Fatal Error angekreidet hat...
Gast
#1013915
> Wenn ich zB. 2 inout signale a und b mit unterschiedlichen > Dimensionen hab, und nur a(0) und b(0) direkt miteinander verbinden > will, muss das ja auch gehen. Hm, alles was mir dazu eingefallen ist hätte eine andere Bedeutung gehabt als "a und b verbinden". Speziell sowas hier:
1 | |
2 | |
würde zumindest formal etwas anderes machen als die Signalzuweisung bei Ports, und wäre für die Simulation untauglich (wie es mit der Synthese aussieht weiß ich nicht). Ich denke mal, die Erfinder von VHDL haben sich dabei gedacht, dass in diesem Fall das Signal a(0) bzw. b(0) ja eigentlich nur ein Signal ist und man deshalb gefäligst auch nur ein Signal hinschreiben soll.
Es gibt aliases. Man kann zB. schreiben signal a : inout std_logic_vector(31 downto 0) alias b : std_logic_vector(3 downto 0) is a(3 downto 0) Das geht schon in die richtige Richtung, hilft mir aber bei meinem Problem auch nicht weiter. Das was du oben geschrieben hast, hab ich probiert. Synthesewerkzeug hat aber gemäkelt (error) weil ich b auf sich selbst zuweise. Aber eigentlich kann es doch nicht sein, dass sowas einfaches und anschauliches nicht in VHDL gehen soll, oder? Ich konnte VHDL schon von anfang an nicht leiden und hätte viel lieber Verilog genommen... aber so schlecht kann VHDL ja nun eigentlich nicht sein, oder?
Gast
#1014035
> Aber eigentlich kann es doch nicht sein, dass sowas einfaches und > anschauliches nicht in VHDL gehen soll, oder? Wie gesagt, ich vermute stark dass "man" in VHDL ein einziges Signal hinschreibt wenn nur eins gemeint ist. > Ich konnte VHDL schon von anfang an nicht leiden und hätte viel > lieber Verilog genommen... aber so schlecht kann VHDL ja nun eigentlich > nicht sein, oder? Wenn sich dieses Problem in Verilog ohne weiteres lösen lässt dann schreib doch das eine Modul um das es geht in Verilog, dazu musst du ja nicht gleich alles ändern was du schon fertig hast. Die Synthesewerkzeuge können ja Verilog/VHDL durcheinander. Und wenn du mit Verilog besser klarkommst dann benutz halt ab jetzt Verilog. Ob VHDL nun gut oder schlecht ist spielt für mich praktisch keine Rolle. Es ist halt der Standard, und gut is. Ändern kann ich es eh nicht. Jedenfalls viel Glück bei deinem Problem!
> signal a : inout std_logic_vector(31 downto 0) > alias b : std_logic_vector(3 downto 0) is a(3 downto 0) Es gibt keine inout Signale, sondern nur Signale, deshalb ist das Beispiel falsch. Nur die Ports einer Komponente können in, out oder inout sein. In der Praxis entspricht dem inout Port ein Tri-state buffer. Hat eine Komponente ein inout Port, so ist meist gedacht das dieses Signal direkt an die Pins des FPGAs geht, denn nur dort befinden sich Tri-state buffer. Zwei Komponenten mit inout Ports innerhalb des FPGAs zu verschalten (also wie ein interner Bus), ist unüblich, da die FPGAs meist keine internen Tri-state Buffer haben. Das ist kein Problem von VHDL, sondern von der zur Verfügung stehenden Hardware. Wenn in Deinen Beispiel die Signale SRAM_DQ : inout std_logic_vector(15 downto 0); die Pins vom externen SRAM sind und data_to_and_from_the_sram dazu gedacht sind, an die externen Pins zu gehen, dann ist CPU0 : nios2 port map ( ..., data_to_and_from_the_sram(15 downto 0)=>DRAM_DQ); richtig. Ein Problem hätte man nur, wenn der Compiler nicht erlauben würde, nur Teile des Vektors zu verbinden.
Stimmt, das inout gehört da nicht hin. Ist mir aus versehen reingerutscht... Wenn ich den SRAM auch im FPGA nachbilden will, beispielsweise um einen SRAM Controller zu testen, brauch ich im FPGA 2 inout ports. Mit einem alias ist es ja auch möglich die zu "verbinden", genau dafür gibt es die Dinger. Nur funktioniert das halt nur von einem schmaleren auf einen Teil eines breiteren vector, nicht umgekehrt... oder ich weis nur nicht wie's umgekehrt geht (ok, ist ziemlich doof bei inout von "von... auf" zu reden). In C/C++ würd ich an der Stelle einfach einen Zeiger auf die Daten nehmen. Dann kann jeder lesen und schreiben.
Gast
#1016045
Du kannst das SRAM nicht "im FPGA nachbilden" da es im FPGA keine bidirektionalen (inout) Signale gibt! Ausserdem ist es auch logisch, dass man zwei inout-Ports nicht mit einander verbinden kann. Um über einen inout-Port etwas sinnvolles (und nicht nur das was man selbst treibt) zu lesen, muss er ja hochohmig gemacht werden. Wenn du nun zwei inout-Ports verbindest, dann würde ja jeder immer das treiben was am anderen anliegt. Die beiden Ports hochohmig zu machen wäre nicht mehr möglich.
Da herrscht vielleicht ein bischen Verwirrung. Ein inout Port ist nicht das selbe wie ein bidirektionales Signal und muß auch nicht ein Tristate sein. Ein inout Port einer Komponente treibt zuerst einmal das Signal, das an die Komponente an diesem Port angeschlossen ist. Zusätzlich wird der Wert, der sich AUSSEN an diesem Signal ergibt, in die Komponente zurückgelesen. Der Wert, der sich außerhalb der Komponente ergibt, muß nicht der selbe sein, wie der den die Komponente selbst schreibt, weil eben mehrere Komponenten das selbe Signal treiben können. Da kommt ein Konzept von VDHL ins Spiel, das sich "resolved signals" nennt. Bei dem resolved signal Typ STD_LOGIC den man in der Praxis verwendet, gibt die Kombination von 'Z' (hochohmig) und einem Wert von '1' wieder '1'. Das simuliert einen Bus mit 2 Komponenten, einer "treibt" hochohmig, der andere '1' -> ergibt wieder '1'. Da man in einem FPGA aber keine internen Tri-states zur Verfügung hat, ist es unüblich, innerhalb eines FPGAs zwei Komponenten mit inout Ports das selbe Signal treiben zu lassen. Das wäre dann ein interner Bus. Was man aber macht, ist den inout Port einer Unterkomponente mit dem inout Port (oder Signal) der sie umgebenden Komponente zu verbinden. Dabei wird das Signal nur weitergereicht.
Gast
#1016090
> Ein inout Port ist nicht das selbe wie ein bidirektionales Signal und > muß auch nicht ein Tristate sein. In der Simulation mag das Stimmen. Für die Synthese macht ein inout-Port nur Sinn, wenn das ganze auch als Tristate verwendet wird. Ansonsten ist schwer zu hoffen, dass auch eine 1 anliegt, wenn man eine 1 treibt, da alles andere einen Kurzschluss verursachen würde!
VHDL ist doch nicht nur auf synthetisierbare Sachen beschränkt. Wenn ich zB. einen PCI Bus und eine eingesteckte PCI-X Karte simulieren will, hab ich genau das selbe Problem, dann hängen 32 Datenleitungen in der Luft. Wenn ich den Pins allen einzeln Namen gebe ist die Sache ja auch überhaupt kein Problem, ich frag mich nur gerade ob VHDL wirklich die Mittel fehlen das syntaktisch elegant auch für teile eines Vektors zu machen. Das ist ja weniger ein Problem ob ein VHDL Simulator/Assembler das vom Prinzip her kann oder ob die Sprache das Konzept unterstützt, sondern ob das auch mit teilen von Vektoren geht. Mit einzelnen Signalen ist es ja mit alias ganz einfach.
Ist es das, was Du suchst?
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
Habe jetzt auch ein bischen herumspielen müssen, aber SigD wird benötigt. Der Compiler wirds dann verschmeißen.
Genau, die Frage ist eben, ob das auch port map und damit auch ohne zusätzliche Komponente funktioniert. Für einzelne Signale und vektoren kleiner oder gleich groß dem gegebenen inout funktioniert das per alias, ich wüsste aber nicht wie man das mit einem größeren Signal macht. Also:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
So funktioniert die Sache problemlos, ohne das man auf das port map angewiesen ist um das umzusetzen (muss ja nicht immer eine extra Komponente sein). Wenn nun aber SigC 16bits, und SigA 32bits breit sind funktioniert das so nicht mehr. Lässt es sich dann wirklich ausschließlich über port map realisieren? Ich hab schon sowas probiert wie
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
Aber das hat erwartungsgemäß nicht funktioniert, genausowenig wie
1 | |
> So funktioniert die Sache problemlos, ohne das man auf das port map > angewiesen ist um das umzusetzen (muss ja nicht immer eine extra > Komponente sein). Dein Problem ist mir wirklich nicht klar. Geht es dir wirklich nur darum dass Du ein Signal SigD konstruieren möchtest, damit Du
1 | |
schreiben kannst anstelle von
1 | |
2 | |
3 | |
4 | |
?? Das erste ist nur eine verkürzte Schreibweise, die sowieso nicht empfehlenswert ist.
Mir geht es ganz allgemein darum, ob man ein Signal aus 2 anderen Signalen konstruieren kann (ohne den krampfigen Umweg über port map und eine extra Komponente).
So ? SigSumme <= Vector1 & Vector2; Macht aus 2 Vektoren einen. Aber ich kann mir nicht denken, dass dies das Problem war.
Genau so - und nun bitte für inout...
Gast
#1016800
Du hast falsche Vorstellungen von "inout". Wie schon vorher geschrieben : es gibt keine inout Signale, Signale haben keine Richtung ! Es geht nur darum wie man Ports einer Unterkomponente mit den Ports der umgebenden Komponente verbindet. Und die Beispiele hatten wir doch schon alle : a) Port in Unterkompontente kürzer als außen : Dein Beispiel von 14:43, auch wenn man auf SigD verzichten kann und direkt schreiben kann dummy : KompA port map (SigA => SigC(15 downto 0)); b) Port in Unterkomponente größer als in Hauptkomponente : Mein Beispiel von 12:16
Gast
#1016872
Und ich habe gefragt, ob das auch anders als mit port map geht!
Gast
#1016930
Willkommen im Forum: Jeder gibt seinen Senf dazu und keiner liest die Frage, denn die ist ja nicht interessant ;) Also: Wenn ich es richtig verstehe, dann ist gefragt, ob man bei zwei Signalen
1 | |
die beiden so zusammenschließen kann, dass eine einzige Resolution Function alle Treiber beider Signale zu einem Ergebnis verwurstelt und dieses Ergebnis auf beiden Signalen zu sehen ist. Korrekt? Ich bleibe allerdings nach wie vor bei meiner Vermutung, dass dies nicht möglich ist und du von vornherein nur ein Signal definieren darfst wenn nur eins gemeint ist. Klingt komisch, ist aber VHDL.
Thread lesen gehört auch dazu ;-). Es ist möglich, siehe oben "alias". Aber alias geht nur wenn man einen Teil oder den ganzen Vektor abbildet, den Vektor als Teil des Bildes zu benutzen geht dagegen nicht bzw. weis ich nicht wie. Wenn das wirklich absicht ist, bestätigt das nur meine Vorurteile gegen VHDL ;).
Gast
#1017028
> Thread lesen gehört auch dazu ;-). Es ist möglich, siehe oben "alias". Hab ich, hab ich ;) Alias definiert ja einen neuen Namen für ein schon vorhandenes Signal, geht also nicht wenn schon zwei Signale vorhanden sind. Naja, immerhin ein Teilproblem gelöst (nämlich den, dass du die Signaldefinition ändern kannst). > Aber alias geht nur wenn man einen Teil oder den ganzen Vektor abbildet, > den Vektor als Teil des Bildes zu benutzen geht dagegen nicht bzw. weis > ich nicht wie. Das bringt mich aber auf eine andere Idee. Momentan definierst du einen Vektor und willst ihn als Teil des Alias-Bildes verwenden, aber das geht nicht. Könntest du statt dessen den Vektor "groß" definieren und einem Teil davon per alias einen anderen Namen geben? Also konkret das Signal als 32-Bit definieren, und dann ein alias für die unteren 16 Bit, bzw. allgemein die "längste" Variante des Vektors per "signal" und alle anderen per "alias" definieren.
Gast
#1017029
Hm sehe grad dass es u.U. um einen Port als "kurzen" Vektor geht, da funktioniert meine Lösung natürlich nicht.
Gast
#1017031
> Wenn das wirklich absicht ist, bestätigt das nur meine Vorurteile gegen > VHDL ;). Meine Meinung dazu steht übrigens noch: Wenn es mit Verilog einfacher geht, dann mach es doch damit! "best tool for the job" und so weiter... da hätte ich gar keine Hemmungen. Bin nur gar nicht so sicher, dass das Problem da nicht auftritt. Sorry für den Dreifachpost.
Langsam geb ich's auf ... > Also: Wenn ich es richtig verstehe, dann ist gefragt, ob man bei zwei > Signalen > > signal a, b : std_logic; > > die beiden so zusammenschließen kann, dass eine einzige Resolution > Function alle Treiber beider Signale zu einem Ergebnis verwurstelt > und dieses Ergebnis auf beiden Signalen zu sehen ist. Korrekt? Es geht niemals (und ganz, ganz sicher auch in Verilog nicht), dass man die beiden Signale so verschaltet, dass alle Änderungen an b auf a sichtbar sind und umgekehrt. Man kann nur ein drittes Signal c erzeugen, das alle Änderungen beinhaltet. Das Beispiel mit Alias ist, wie oben geschrieben falsch. Alias ist nur ein weiterer Name für (einen Teil) eines bestehenden signals; beide Namen zeigen auf das selbe Signal. Da ist es klar dass einen Änderung unter beiden Namen sichtbar ist. > Wenn das wirklich absicht ist, bestätigt das nur meine Vorurteile > gegen VHDL ;). Die Vorurteile kann ich Dir nicht nehmen, ich hab's probiert. Ich kann Dir aber versichern, dass Du von VHDL falsche Vorstellungen hast. Deine Bemerkung mit dem Zeiger läßt vermuten, dass Du VHDL eher als Programmiersprache siehst, was die Sache eben nicht ganz trifft.
Es geht letztlich nicht darum was elektrisch, sondern formal passiert. Ob der Compiler das intern zum selben Signal auflöst oder ob man das elektrisch zusammenschaltet ist äquivalent. Ich fang jetzt nicht damit an, dass man VHDL auch für 'ne Touringmaschine oder einen Kellerautomaten übersetzen könnte und dort Konzepte wie "elektrisch zusammenschalten" garnicht existieren ;). Wenn ich meinen eigenen VHDL Assembler anwerfe (den zwischen den Ohren) könnte ich beim Übersetzen der Sprache ein Alias erstmal zu 2 Signalen auflösen die ich dann elektrisch verbinde, weil es meine Zielhardware kann. > Das bringt mich aber auf eine andere Idee. Momentan definierst du einen > Vektor und willst ihn als Teil des Alias-Bildes verwenden, aber das geht > nicht. Könntest du statt dessen den Vektor "groß" definieren und einem > Teil davon per alias einen anderen Namen geben? > Also konkret das Signal als 32-Bit definieren, und dann ein alias für > die unteren 16 Bit, bzw. allgemein die "längste" Variante des Vektors > per "signal" und alle anderen per "alias" definieren. Allerdings steht der Vektor vom DRAM ja schon oben in der Komponente drinnen. Dann müsste ich dem eines der Aliase zuweisen. Vielleicht hab ich's aber auch nicht richtig verstanden.
Dir ist nicht zu helfen ....
Meine Güte, ist es denn so schwer zu verstehen?
> Es geht niemals [..], dass man die beiden Signale so verschaltet ...
Ich hab nirgends 2 Signale vorrausgesetzt! Wenn es mit einem Alias geht,
ist mir das genauso recht, ein Alias ist kein Signal. Stell dir
meinentwegen ein Alias der Länge 32 vor, bei dem die ersten 16 Elemente
ein anderes Signal referenzieren als die letzten 16 Elemente.
Gast
#1017854
> Es geht niemals (und ganz, ganz sicher auch in Verilog nicht), dass man > die beiden Signale so verschaltet, dass alle Änderungen an b auf a > sichtbar sind und umgekehrt. 1. Warum nicht? In Realität kann ich doch auch z.B. zwei an sich getrennte Tristate-Busse einfach per Draht zusammenlöten, und dann passiert genau das. 2. Wenn es mit zwei Signalen nicht geht, wie dann? Zwei Signale zu verwenden war ja nur ein möglicher Lösungsansatz für das Problem. > Das Beispiel mit Alias ist, wie oben geschrieben falsch. Alias ist nur > ein weiterer Name für (einen Teil) eines bestehenden signals; beide > Namen zeigen auf das selbe Signal. Da ist es klar dass einen Änderung > unter beiden Namen sichtbar ist. Aber genau das ist doch gewünscht, nur wissen weder I_ H. noch ich, wie man das Alias wie gewünscht definiert. Hilfreich wäre eine der beiden folgenden Lösungen: 1. Den äußeren Port als 16 Bit, ein internes Dummy-Signal mit 16 Bit und ein 32-Bit Alias, welches beide zusammenfaßt. Die innere Komponente wird an das Alias angeschlossen. 2. Ein lokales 32-Bit-Signal, an welches die innere Komponente angeschlossen wird. Ein äußerer 16-Bit-Port, welcher kein eigenes Signal, sondern nur ein Alias für die unteren 16 Bits des internen Signals ist. > Die Vorurteile kann ich Dir nicht nehmen, ich hab's probiert. > Ich kann Dir aber versichern, dass Du von VHDL falsche Vorstellungen > hast. > Deine Bemerkung mit dem Zeiger läßt vermuten, dass Du VHDL eher als > Programmiersprache siehst, was die Sache eben nicht ganz trifft. Wo hast du das denn rausgelesen? Ich sehe in der Bemerkung mit den Zeigern einen Versuch, dir das Problem deutlich zu machen, welches du scheinbar immer noch nicht verstanden hast. Gerade deshalb wäre es vllt. angebracht, etwas weniger überheblich zu sein. ----- @I_ H. : Ich würde an deiner Stelle nicht mehr weiter an dem Problem rumkauen. Es sieht fast so aus, als hätte VHDL einfach keine "saubere" Lösung parat. Ich würde statt dessen eine äußere "wrapper"-Entity bauen (ist ja oben schon gesagt wie es damit geht) und gut is. Es lohnt sich einfach nicht, da noch mehr Zeit reinzustecken. Wie von Klaus angedeutet geht es mit Verilog wahrscheinlich auch nicht einfacher, aber probieren kannst du es ja nochmal.
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.