Forum: FPGA, VHDL & Co. Interne Tristates


von Christian P. (kron)


Lesenswert?

In einem der PDFS im "Synthesefähiger Code"-Thread steht,
dass Tristates nur in der Top-Ebene für IN/OUT verwendet werden 
"dürfen".

Ich habe aber einige Designs, wo ich intern Tristates nutze,
wenn z.B. mehrere Komponenten ein Data_out-Signal nutzen.

Ist das okay, oder gibt es dafür einen saubereren Weg?

Anmerken muss ich dazu, dass bei der Synthese die Meldung
"16 internal tristates are replaced by logic (pull-up yes): D_OUT<0>..."
kommt, was sicherlich damit zu tun hat.
Ich konnte mir aber bisher keinen Reim darauf machen.

von +++ (Gast)


Lesenswert?

Da Logikbausteine keine internen Tristate-Treiber haben wird das m.W. 
mit Multiplexern aufgebaut.
Die Mitteilung "(pull-up yes)" verstehe ich so, dass der Mux alle 
Ausgänge auf "1" legt, wenn alle Signale auf High-Z schalten sollen.
Der saubere Weg wäre wohl direkt Multiplexer zu verwenden!?

von Falk (Gast)


Lesenswert?

@Christian Peters

>Ich habe aber einige Designs, wo ich intern Tristates nutze,
>wenn z.B. mehrere Komponenten ein Data_out-Signal nutzen.
>Ist das okay, oder gibt es dafür einen saubereren Weg?

Es gibt einen sauberen Weg. Einfach einen MUX verwenden bzw. anstatt 
eines bidirektionalen Signals mit Tristate zwei unidirektionale.

>Anmerken muss ich dazu, dass bei der Synthese die Meldung
>"16 internal tristates are replaced by logic (pull-up yes): D_OUT<0>..."
>kommt, was sicherlich damit zu tun hat.

Ja.

MfG
Falk

von Christian P. (kron)


Lesenswert?

> Es gibt einen sauberen Weg. Einfach einen MUX verwenden bzw. anstatt
> eines bidirektionalen Signals mit Tristate zwei unidirektionale.

Ok, letzteres fällt aus, da nunmal ein bidirektionaler Bus
am FPGA hängt, da komm ich nicht weg. :)

Hm, Mux, d.h., nur damit ich es richtig verstehe,
in den einzelnen Komponenten lege ich das jeweilige
Signal auf den Datenausgang, und in der TOP-Ebene
mache ich dann sowas wie:
1
mux_signal <= prozess1_enable & prozess2_enable & prozess3_enable;
2
3
case mux_signal is
4
when "100" =>
5
 D_OUT <= d_out_prozess1;
6
when "010" =>
7
 D_OUT <= d_out_prozess2;
8
when "001" =>
9
 D_OUT <= d_out_prozess3;
10
when others =>
11
 null;
12
end case;

Ist das so ungefähr richtig?
Aber damit habe ich ja viel mehr Signale als bei der Z-Lösung,
weil ich ja jetzt für jeden Prozess ein eigenes d_out-Signal brauche,
oder nicht?

Ach ja, problematisch könnte bei der ganzen Sache noch
die Tatsache sein, dass ich zwei verschiedene Clocks habe
(eine vom DSP, eine FPGA).
Dann geht das mit dem MUX nicht so einfach, weil manche
der Komponenten mit DSP-Clock laufen und manche mit der FPGA?!

Sorry, noch ne ganz andere Frage,
wenn ich in der TOP-Ebene nebenläufige Anweisungen nutze,
also ohne Prozess, sondern mit "when ... else", mit welchem
Takt laufen die dann eigentlich?

von Neuer G. (vhdl_progger)


Lesenswert?

Christian Peters wrote:

> Sorry, noch ne ganz andere Frage,
> wenn ich in der TOP-Ebene nebenläufige Anweisungen nutze,
> also ohne Prozess, sondern mit "when ... else", mit welchem
> Takt laufen die dann eigentlich?

Das läuft dann ohne Takt ab, asynchron, wie bei einem
normalen UND, -ODER Gatter (oder was auch immer).

Übrigens:

Selbst wenn du die Anweisung "process ..." benutzt
läuft das ganze nicht unbedingt mit einem Takt ab.
Im Prozess muß mindestens eine Anweisung
wie

  if rising_edge(clk) then ....

oder

  if (clk'event and clk = '1') then

stehen, damit das ganze getaktet abläuft

Gruß

Ralf

von Christian P. (kron)


Lesenswert?

Ja, Ralf, richtig, das stimmt natürlich,
das ist bei mir schon "selbstverständlich",
deswegen hatte ich das nicht korrekt ausgedrückt.

Aber ist das nicht problematisch, ich denke,
man soll asynchrone Sachen soweit wie möglich vermeiden?!

Ich hab in einem Projekt jetzt mal so einen Mux integriert,
spart ein bißchen Platz, aber ist dafür langsamer!
Hier mal die Daten vorher, in Klammern dahinter sind die
jeweiligen Werte danach, falls sie sich geändert haben:

Number of Slices:           128  out of   1920     6%  (119)
Number of Slice Flip Flops: 169  out of   3840     4%  (165)
Number of 4 input LUTs:     113  out of   3840     2%
Number of bonded IOBs:      71  out of    141    50%
IOB Flip Flops: 34
Number of GCLKs:            1  out of      8    12%

Minimum period: 8.465ns (Maximum Frequency: 118.132MHz (97.293MHz)
Minimum input arrival time before clock: 8.089ns       (6.126ns)
Maximum output required time after clock: 10.027ns     (7.660ns)
Maximum combinational path delay: 10.904ns             (11.133ns)

Da kann man doch eigentlich nicht sagen,
dass das mit dem MUX "besser" ist, wenn es
vorher mit den internen Tristates (im Quellcode Tristates)
schneller war, oder?

von na (Gast)


Lesenswert?

Durch pull-up-Widerstände wird das erzeugt, was man bei std_logic eine 
"schwache 1" nennt. Das heißt, diese kann, wie eben bei tristate nötig, 
überschrieben werden. Diese Technologie ist nicht durch LUTs oder 
sonstwas simulierbar sondern muss natürlich vorhanden sein. Anscheinend 
ist sie es, wenn ISE das sagt, also kann man sie auch nutzen.

von Schlumpf (Gast)


Lesenswert?

@ Christian

> Ok, letzteres fällt aus, da nunmal ein bidirektionaler Bus
> am FPGA hängt, da komm ich nicht weg. :)

Du kannst doch von deinem externen bidirektionalen Bus intern 
unidirektional weiterarbeiten:

nach dem Prinzip:

internes Din liest immer Dextern
Dextern wird mit dem internen Dout belegt, wenn OE am PFGA aktiv ist




von Roger S. (edge)


Lesenswert?

naja, dein MUX ist in realitaet ein latch, wenn du wirklich ein MUX 
haben willst dann solltest du in allen when's dein D_OUT setzen.

z.B so:
1
case mux_signal is
2
when "100" =>
3
 D_OUT <= d_out_prozess1;
4
when "010" =>
5
 D_OUT <= d_out_prozess2;
6
when "001" =>
7
 D_OUT <= d_out_prozess3;
8
when others =>
9
 D_OUT <= (others=>'X');
10
end case;

Cheers, Roger

von Schlumpf (Gast)


Angehängte Dateien:

Lesenswert?

Hab mal ne Prinzipskizze gemacht, wie sowas funktionieren kann...
Allerdings sind alle Eingangsregister, Glitchfilter etc. weggelassen

Vielleicht hilft dir das weiter

von Christian P. (kron)


Lesenswert?

Danke Schlumpf (und auch alle anderen!),

ja, das hat mir geholfen.
Stück für Stück wird man schlauer. :)

von Schlumpf (Gast)


Lesenswert?

gern geschehen ;-)

von hhanff (Gast)


Lesenswert?

Hallo! Ich habe die gleiche Warnung von ISE:

WARNING:Xst:2042 - Unit data_to_ram: 16 internal tristates are replaced 
by logic (pull-up yes): data_out<0>,.....

Allerdings verstehe ich nicht warum, da ich data_out in der 
entsprechenden Entity gar nicht Tri State-fähig gemacht habe. (s.Code)
1
entity data_to_ram is
2
  
3
  generic (
4
    FREQ : natural := 27_000);          -- global frequency
5
6
  port (
7
    load_clk         : in  std_logic;   -- load clock
8
    rst_load_clk     : in  std_logic;
9
    load_n           : in  std_logic;
10
    data_out         : out std_logic_vector(15 downto 0);  
11
    tri_state_enable : out std_logic;
12
    data_in          : in  std_logic_vector(7 downto 0) 
13
    );
14
end data_to_ram;
Aber: data_out wird in meinem Top Level File unter bestimmten 
Bedingungen auf einen Tri-State-fähigen Ausgang geschaltet. Hängt die 
Fehlermeldung damit zusammen?

Gruß aus Bremen,

Hendrik

von hhanff (Gast)


Lesenswert?

Oder hängt das mit dieser Anweisung zusammen:
1
data_out <= (others => 'Z');
die ich weiter unten in der Architecture mache???

von frank (Gast)


Lesenswert?

warum setzt du das data_out auf "Z"? sollte nicht nötig sein, wenn es 
ein reiner Output ist. Im Zweifel auf "x" setzen.

frank

von hhanff (Gast)


Lesenswert?

Im Top Level File führt data_out auf einen IOPAD in einem XILINX FPGA. 
Der Grund ist zum einen weil für mich die Simulation dann 
übersichtlicher ist. Darüber hinaus bin ich mir nicht sicher bin, ob man 
data_out auf 'Z' setzen MUSS, wenn das IOPAD Daten von aussen empfangen 
soll.... Kann mir das vielleicht auch mal jemand erklären? Aus der 
Application Note von Xilinx werde ich nicht schlau.

von Falk B. (falk)


Lesenswert?

@ hhanff (Gast)

>Im Top Level File führt data_out auf einen IOPAD in einem XILINX FPGA.

Naja, aber wenn das Tristate in einem Modul zugewiesen wird, welches 
dann als Component eingebunden wird dann versckluckt sich ISE bisweilen. 
Darum besser nur Tristates echt auf dem Toplevel verwenden.

>übersichtlicher ist. Darüber hinaus bin ich mir nicht sicher bin, ob man
>data_out auf 'Z' setzen MUSS, wenn das IOPAD Daten von aussen empfangen

Aber sicher muss man das. Wie sollen die Daten sonst von der externem 
Quelle getrieben werden?

MFG
Falk

von hhanff (Gast)


Lesenswert?

OK. Danke schonmal für den 2. Teil der Antwort.
Den ersten Teil der Antwort versuche ich dann mal zu implementieren.

Danke,

Hendrik

von hhanff (Gast)


Lesenswert?

OK. Ich habe nun auch den 2. Teil implementiert und alle 
Tri-State-Zuweisungen ins Top-level verlegt.
Leider bleibt die Warnung bestehen. Hat noch jemand ne Idee???

von hhanff (Gast)


Lesenswert?

Manmanman... schade dass man Beiträge nicht löschen kann. Ich hab den 
Fehler gefunden. Er lag zwischen den Ohren.
Ich hab vor kurzem versucht mein Design mit Hilfe von ISE zu optimieren. 
Dabei bin ich folgenden Schritten gefolgt:
1. Right-click the Synthesize - XST process.
2. Select Properties from the menu.
3. Click the Xilinx Specific Options tab to display this property.

und dann habe ich den Eintrag "Convert Tristates to logic" auf YES 
gesetzt.

ABER: Jetzt bekomme ich haufenweise diese Info:
NgdBuild:928 - A pullup 'data_out_s<15>.PULLUP' was added to net 
'data_out_s<15>'

Google und Xilinx haben keine Antwort.... Hat jemand ne Idee???

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.