Forum: FPGA, VHDL & Co. Ausgangssignale mehrerer Blöcke OR'en


von Michael S. (decimad)


Lesenswert?

Halli Hallo,

ich habe jetzt nun einen Schieberegister zur Kooperation und 
Reservierung von Takten auf einem Bus. Es ist konstruktiv gesichert, 
dass nur genau ein VHDL-Block pro Taktzyklus versucht, sich Zeit auf dem 
Bus und damit in dem Schieberegister zu reservieren. Aber nur die Blöcke 
selber wissen eigentlich, in welchem Takt sie wollen, daher möchte ich 
dieses Implementierungsdetail nicht in den Vater-Block rüberschiffen.
Gibt es irgendwie eine Möglichkeit, ein out-Signal in Sub-Knoten zu 
geben, auf das diese sich "OR"en können, so wie sie wollen?
Also dass ich ein Signal definiere und dann irgendwie eine Referenz zu 
diesem Signal in die Unterknoten geben kann, sodass ich im obersten 
Knoten nicht manuell viele Signale "OR"en muss?
Hrmmm, schwer zu beschreiben, hoffentlich hat's geklappt.

Viele Grüße,
Deci

von Schlumpf (Gast)


Lesenswert?

Michael S. schrieb:
> Hrmmm, schwer zu beschreiben, hoffentlich hat's geklappt.

Bei mir jedenfalls hat es nicht geklappt... :-)

von Michael S. (decimad)


Lesenswert?

Also, hrmmm, ich möchte in einen Block X ein Signal Y haben, das die 
Ver-Oderung von Signalen einiger Unterblöcke Zn darstellt.
Ohne aber im Block X zu schreiben:
1
Z1 : ...;
2
Z2 : ...;
3
Z3 : ...;
4
Z4 : ...;
5
Z5 : ...;
6
7
Y(3) <= Z1_out or Z4_out or ...; -- das hier möchte ich nicht
8
Y(2) <= Z5_out or Z1_out or ...; -- das hier auch nicht

sondern ich möchte den Blöcken Zn Y mit auf den Weg geben, auf das sie 
sich selber drauf OR'en, wie sie es für richtig halten.
Mir ist irgendwie klar, dass die gebildete Funktion überhaupt nur für 
eine allumfassende Oder-Verknüpfung eindeutig ist, drum frage ich mich, 
ob man sich die Mühe gemacht hat, soetwas zu ermöglichen.

von Hmm (Gast)


Lesenswert?

Such mal nach "resolve_logic". Da kannst Du ein wired-or nachbilden.

von Michael S. (decimad)


Lesenswert?

Ahhh, ich sehe! Dankeschön! Lässt sich das mit Xilinx ISE Webpack für 
interne logik so synthetisieren, wie ich es mir vorstelle? Ich sehe da 
halt sofort wieder Tristate-Inouts mitschwingen und das ist ja nicht 
wirklich, was ich möchte.

Viele Grüße,
Deci

von Hmm (Gast)


Lesenswert?

Offen gesagt, weiss ich es nicht, für welche FPGAs oder CPLDs das 
synthetisierbar ist. Das musst Du ausprobieren.
Auch das Xilinx-Forum könnte evtl. dazu was enthalten.

Aber was "Tri-State" anbetrifft, hast Du erstens nicht geschrieben, das 
Du das nicht willst und zweitens spricht eigentlich nichts dagegen.

von Schlumpf (Gast)


Lesenswert?

ach sooo... du meinst einfach ein wired-or?

Nachdem es in den FPGAs üblicherweise keine Tristate-Buffer gibt, kann 
sein, dass deine Synthese das vielleicht "frisst" aber sie wird es dann 
trotzdem in ganz normale Logik umbauen.
Daher kannst es auch gleich als solche beschreiben.
Oder geht es dir darum, ein paar Zeilen Code weniger zu tippen?

von Michael S. (decimad)


Lesenswert?

Hallo!
Es geht mir hauptsächlich darum, dass ich versucht habe, ein Design zu 
bauen, das recht modular aufgebaut ist, wo ich einfach Blöcke dazubauen 
wollte, die eben alle am gleichen Datenbus lauschen und auf einen 
gemeinsamen Datenbus ausgeben. Das besprochene Signal dient der 
Kooperation und dafür habe ich schon ein "Protokoll" definiert, an das 
sich die Unterblöcke halten müssen (lässt sich auch Prima 
durchsimulieren, ob sie das auch wirklich tun).
Die übergeordnete Instanz kümmert es gar nicht, was die Blöcke nun genau 
machen. Aber aufgrund dieses besprochenen Signals muss die übergeordnete 
Instanz doch wieder etwas sehr genaues von den Blöcken wissen, nämlich 
auf welches Y(x) der Ausgang vom Block ge-ORt werden soll. Ich möchte 
lieber, dass die übergeordnete Instanz den Blöcken ein Signal zur Hand 
gibt, auf das sie sich dann eigenständig passend ORen, sodass die 
übergeordnete Instanz zwar noch dieses Signal zur Verfügung stellen 
muss, sonst aber überhaupt nicht weiß, was genau die Unterblöcke damit 
machen. Das Übersetzungstool würde dann bestimmen, welche Blöcke sich 
auf das Signal und auf welches Element davon ORen und dann die 
entsprechende Zuweisung selbständig generieren.
Das ist wie gesagt nur ein internes Kollaborations-Signal, das von einem 
anderen Block aufgefangen, zwischengespeichert und weiterverarbeitet 
wird etc. und dann wiederum allen Knoten signalisiert, was sie dürfen 
oder was nicht.

Mein Problem lautet gerade, dass sich meinetwegen 20 Blöcke einen 
Zwei-Kanal-Bus zum Schreiben teilen müssen und dieses Signal ist Eingang 
für einen Schieberegister, auf dem man sich im voraus Taktschlitze 
reservieren kann.
Der erleichternde Umstand, warum das funktionieren sollte, ist, dass 
immer nur ein Block pro Takt mit irgendwas startet, also gibt es bei der 
Reservierung von Taktschlitzen keine Möglichkeit für Kollisionen, wohl 
aber, wenn sie nach einer variablen Anzahl von Takten fertig werden.

Gibt es andere ähnlich simple und ressourcenschonende Lösungsansätze, 
damit X Entitäten sich so absprechen, dass sie 2 Kanäle verwenden, ohne 
dass es zu Kollisionen kommt?

Zuerst wollte ich da einen Block hinterschalten, der einen Flag-Vektor 
bekommt und dann einzelnen Blöcken signalisiert, dass sie warten müssen, 
oder auf welchen Kanal sie dürfen. Aber die Logik erschien mir schon 
sehr ausufernd und ich brauchte breite Register, Blockspezifische 
Rückführsignale (also die Komplexität der Ergebnisses aber auch des per 
Hand zu schreibenden VHDL-Codes) stieg direkt mit der Anzahl der Blöcke) 
etc.. Das versuche ich mit diesem "geteilten" Schieberegister-Ansatz 
jetzt zu vermeiden.

von Christian R. (supachris)


Lesenswert?

Ich mach das immer so, dass ich für die Ausgangsvektoren der Module, die 
ver-ordert werden sollen, ein Array anlege und die Ausgänge dann erst 
mal jeden auf einen Array-Index verdrahte (Index über Constant-Makro in 
einem Package für leichte Änderungen). Und mit einer kleinen for loop 
dann alle im Array befindlichen Vektoren zu einem Ausgangsvektor 
ver-ordern. Meist noch eingeschränkt über ein MAX_READ_REG Constant, 
damit nicht so viele sinnlose Warnungen in ISE auftauchen.
1
  GenOr : Process(ReadData)
2
    variable temp : std_logic_vector(31 downto 0);
3
  Begin
4
    temp := ReadData(0);
5
    for i in 1 to MAX_READ_REG loop
6
      temp := temp or ReadData(i);
7
    end loop;
8
    READ_DATA <= temp;
9
  End Process;

Erzeugt ein generisches OR ohne viel Schreibaufwand.

von Michael S. (decimad)


Lesenswert?

Hey, das wäre auch eine Möglichkeit, vielen Dank!
Die Unterblöcke schreiben ja nicht auf alle Elemente des Signals, aber 
wenn sie das nicht tun, so kann ich wohl davon ausgehen, dass die 
Synthese die unbeschriebenen bzw. konstant auf 0 beschriebenen Elemente 
hinter wegoptimiert, oder?
Dann muss ich zwar immernoch im "Über"-Block Signale definieren pro 
Block, aber muss mich wenigstens nicht mehr mit deren Werten 
auseinandersetzen und die Kombination funktioniert als Schleife und muss 
somit kaum angepasst werden.
Das klingt nach einer akzeptablen Lösung, vielen Dank!

Viele Grüße,
Deci

von Christian R. (supachris)


Lesenswert?

Michael S. schrieb:
> so kann ich wohl davon ausgehen, dass die
> Synthese die unbeschriebenen bzw. konstant auf 0 beschriebenen Elemente
> hinter wegoptimiert, oder?

Klar, ich initialisiere das Array dann auch immer auf Nullen, da gibts 
bloß eine Warnung, dass der Default-Wert verwendet wird, und später 
wirft der di nicht genutzten sowieso raus.

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.