Forum: FPGA, VHDL & Co. VHDL-Tristatebuffer will nicht


von Sebastian H. (Gast)


Angehängte Dateien:

Lesenswert?

Hi,

ich versuche gerade einen Tristatebuffer in VHDL zu implementieren aber
irgendwas stimmt da nicht. In CFG_DATA müssten doch nach dem Einschalten
der Spannung nur Nullen stehen. Das ist aber nicht der Fall da ich bei
meinem Aufbau zwei Bit von CFG_DATA auf LEDs ausgebe und die leuchten
(also muß da wohl eine 1 drin stehen).
Ich bin mir sicher ihr seht den Fehler sofort und könnt mir sagen woran
es liegt!

Danke & Gruß,
Sebastian H.

von Sven Johannes (Gast)


Lesenswert?

Moin...

Bist du sicher, dass dein FPGA (welcher?) Tri-Buffer hat?

Ansonsten ziemlich unangenehm zu lesen, aber wenn mit dem ganzen
asynchronen Gehühner nichts Unerwartetes passiert, sollte tatsächlich
eine '0' an CFG_Data anstehen.

--
 SJ

von Sebastian H. (Gast)


Angehängte Dateien:

Lesenswert?

Hi,

ich verwende einen XC9572 und der hat doch laut DB Tri-Buffer.
Das asynchrone Gehühner gefällt mir auch nicht, hab aber noch nie
einen
Tri-Buffer verwendet und weiß nicht so wirklich wie ich das WR und RD
Signal gleichzeitig vernünftig handhaben soll.

Constraints Editor (Ports) stehen manche als TRI OUTPUT und manche als
BIDIR drin. ??? (siehe Anhang)

Wäre schon wenn du mir ein paar Tipps geben könntest wie man das
sinnvoll umsetzen kann.

von Sven J. (svenj)


Lesenswert?

Moin...

Ein 9572 ist, nebenbei gesagt, ein CPLD, kein FPGA. Macht aber nichts,
nur die Benutzung dürfte sich ändern.

Dem Bus <D> werden da verschiedene Funktionen angedacht. Einige sind
Bidirektional, also Ein-/Ausgänge, andere sind die gewünschten Tristate
Buffer. Schon reichlich herb das in einem Bus zu mischen...

Auf alle Fälle müssen alle Pin das gleiche IO Interface eingestellt
bekommen und um den Z State zu benutzen wirst du auch noch ein enable
Signal bedienen müssen. Finde ich jetzt so gar nicht in deinem Code.
Nebenbei: Bist du sicher das es einen InOut-Tristate Buffer gibt?

--
 SJ

von Tobias O. (Gast)


Lesenswert?

Ich weiss leider nicht wieso du soviel Code brauchst um einen Tristate
Buffer in VHDL zu beschreiben.

Bei mir sieht das so aus

IN_DATA    <= INOUT_DATA;
INOUT_DATA <= OUTDATA when WRITE_ENABLE = '1' else (others 'Z');

oder wenn WRITE_ENABLE ein Vector ist, dann vervielfache ich halt einen
einzelnen Buffer mittels Generate Anweisung.
Hinter dem Buffer sind dann halt die IO-Register platziert.
Hoffe das hilft dir weiter.

von FPGAküchle (Gast)


Angehängte Dateien:

Lesenswert?

Das Problem ist wohl das im Multiplexer einem SIGNAL 'Z' zugewiesen
wird. Da will der interne Tristates draus machen. Das geht zwar bei
Spartan2/2E, die haben interne tristates (TBUF) aber das willst du
nicht. Du willst nur einen Tristateport (also extern 'Z'). Also am
besten Z nur OUT oder INOUT PORTS der Top-Level zuweisen. Ansonsten
habe ich den Code etwas ent-"krautet".

von FPGAküchle (Gast)


Lesenswert?

Hm besser wäre wohl, statt:

[vhdl]
READ_BUS : IN_DATA <= D;

  SET_CFG_REG : PROCESS(WR)
  BEGIN
    IF WR = '1' AND WR'event THEN
      IF OUT_EN /= '1' THEN
        CFG_DATA <= IN_DATA;
      END IF;
    END IF;
  END PROCESS SET_CFG_REG;
[\vhdl]

besser:
Hm besser wäre wohl, statt:

[vhdl]
  SET_CFG_REG : PROCESS(WR)
  BEGIN
    IF WR = '1' AND WR'event THEN
      IF OUT_EN /= '1' THEN
        CFG_DATA <= D;
      END IF;
    END IF;
  END PROCESS SET_CFG_REG;
[\vhdl]

von Sebastian H. (Gast)


Angehängte Dateien:

Lesenswert?

@ Sven

Hab nie behauptet, daß der 9572 ein CPLD ist, oder?
Das enable Signal sollte durch das OUT_EN realisiert werden. Mit dem
Tristate Buffer bin ich mir eigentlich ziemlich sicher, ob er InOut ist
aber nicht so.

---

Hab die Sache jetzt mal umgeschreiben. Hab aber jetzt ein anderes
Problem, der 9572 ist zu klein (91 statt 72). Kann mir irgendwie nicht
ganz vorstellen das ein Zähler (bis 44) und der Rest (siehe Anhang)
nicht in den 9572 passt. Kann man die Schieberegister nicht anders an
den Tristate Buffer anschliessen?

Gruß,
Sebastian

von FPGAküchle (Gast)


Lesenswert?

Mach doch aus den write enables ein shiftregister, spart counter und
decoder.

von Tobias O. (Gast)


Lesenswert?

Schick mal zu deinem VHDL auch die Entity mit damit man mal die ISE
anwerfen kann um sich das ganze als RTL anzuschauen.

von Sebastian H. (Gast)


Lesenswert?

Danke für den Code (funktioniert soweit und passt rein) und die Tipps!
Werd alles nochmal überarbeiten. Ich muß jetzt erstmal eine Verdrahtung
auf der Platine checken, ob da alles stimmt.

Gruß,
Sebastian

von FPGAküchle (Gast)


Lesenswert?

Oder mit richtigen counter:
1
signal RD_CNT : STD_LOGIC_VECTOR(2 downto 0) := (others => '0');
2
3
WRITE_ENABLE: process(RD, RESET)
4
begin
5
  if RESET = '1' then
6
    RD_CNT := (others => '0');
7
  elsif RD = '0' and RD'event then
8
             if rd_cnt = "011" then
9
                rd_cnt <= "000";
10
             ELSE 
11
                 RD_CNT <= RD_CNT +1;
12
             END IF;
13
  end if;
14
end process WRITE_ENABLE;
15
16
      WRITE_4_ENABLE <= '1' WHEN RD_CNT = "011" ELSE '0';
17
      WRITE_3_ENABLE <= '1' WHEN RD_CNT = "010" ELSE '0';
18
      WRITE_2_ENABLE <= '1' WHEN RD_CNT = "001" ELSE '0';
19
      WRITE_1_ENABLE <= '1' WHEN RD_CNT = "000" ELSE '0';

Allerdings sind die enables jetzt ungebuffert, aber spart FF und ein
CPLD ist schnell genug. Dann kannst Du noch ein paar Optimierungen
anschalten. Du optimierst doch auf AREA?

von Sebastian H. (Gast)


Angehängte Dateien:

Lesenswert?

Wollte mich schon eher melden, bin aber mal wieder nicht auf die Seite
gekommen. (Error 505)

Hab jetzt das Konfigurationsregister rausgeworfen. Mußte die
Lesezugriffe auf drei begrenzen da die FF sonst nicht ausgereicht
hätten. Der Counter erhöht sich jetzt bei der steigenden Flanke.
Dadurch wollte ich sicherstellen das die ENABLE Signale nicht während
des Lesezugriffs umschalten.

Im Constraints Editor (Ports) stehen jetzt alle Ds als TRISTATE drin.

An den Optimierungen hab ich nichts verstellt. Sind alle auf Default.

Das komplette Projekt (von CPLD1) hängt im Anhang. Ich hoffe doch, dass
euch .rar keine Probleme macht.
Die Signale IN_1 und IN_2 kommen von einem zweiten CPLD.

Bekomme jetzt aber eine Warnung:

WARNING:Cpld:158 - We have detected that a large number of internal
signals may be switching at the same time. To avoid potential
simultaneous switching/ground bounce issues, please contact Xilinx
customer support for more information.

Gruß,
Sebastian

von FPGAküchle (Gast)


Angehängte Dateien:

Lesenswert?

-Optimieren auf wenig FF: Hab mal (wieder) screenshots von Einstellungen

 beigefügt, die vielleicht noch 10-20 % FF sparen.

-Warning: soll heissen an den Flanken der Outputs können heftige
Unter/Überschwinger sein und man sollte die Betriebsspannung richtig
gebuffert haben (mind. 10/100 nf an jedem Vcc/GND Pärchen. Beim FPGA
würde ich sagen unkritisch, CPLD habe ich mit der warning noch nicht
praktisch ausprobiert.

Mal Scope dranhängen, ich hätte aber auch beim CPLD erstmal keine
bedenken.

von FPGAküchle (Gast)


Angehängte Dateien:

Lesenswert?

Hm, ich habe den counter in einen extra Process geschoben, so wie der
beschrieben wahl (an vier stellen inkrement) wird der XST wohl kein
countermakro sondern wüste Logik (gross) einfügen.

Problem könnten auch die drei Signale mit 'event sein, heisst drei
taktnetzwerke. Die XC95xxx sind wohl für 1 oder 2 Taktnetzwerke (?)
optimiert.

Statt 'event besser rising_edge() oder falling_edge(), macht (fast)
dasselbe, ist die selbe Hardware aber übersichtlicher.

Anbei der überarbeitete Code (evtl. inkl. Tipp- & Dengfehler).

von Sebastian H. (Gast)


Lesenswert?

Danke!

Hat fast alles gepasst. Die rising_edge() oder falling_edge()
Funktionen sind nur mit den BIT-Typ nicht zufrieden gewesen.

Es macht den Anschein als wäre die(oder doch das/der) RTL-Schematic
jetzt übersichtlicher.

Irgendwas stimmt halt mit den Tristate-Buffer noch nicht. Sobald ich
die acht Datenleitungen an den Controller hänge steigt der aus.
Abblockkondensatoren verwende wo es nur geht. Die Versorgung ist auch
gut gepuffert. Außerdem haben Controller und die CPLDs nur eine
gemeinsame Masse. ???

Ich werd jetzt zum Test mal einen 74541 dazwischen hängen. Die Freigabe
werd ich mit den ENABLE Signalenerzeugen.

Gruß,
Sebastian H.

von Sebastian H. (Gast)


Lesenswert?

Hab den Fehler gefunden. Der Controller betätigt das RD Signal auch wenn
er auf interne Adressen zugreift. Und dann muß der Treiber aber
hochohmig bleiben, sonst dreht der Controller durch. Hab also noch nen
nen CS Signal dazugenommen. Jetzt funktioniert es soweit. Mal sehen wie
sich jetzt der Rest der Schaltung verhält. ;)

Hast du vielleicht noch eine Idee wie man den GTS-Pin nutzen kann. Hab
in der ISE nichts gefunden. (typisch Anfänger ;))
1
  WR_EN <= '1' WHEN (RD = '0' AND CS = '0') ELSE '0'; 
2
3
  WR_1_EN <= '1' WHEN (RD_CNT = "00" AND WR_EN = '1') ELSE
4
'0';
5
  WR_2_EN <= '1' WHEN (RD_CNT = "01" AND WR_EN = '1') ELSE
6
'0';
7
  WR_3_EN <= '1' WHEN (RD_CNT = "10" AND WR_EN = '1') ELSE
8
'0';

Gruß und Danke,
Sebastian H.

von Klaus F. (kfalser)


Lesenswert?

Funktioniert das überhaupt?
1
WR_1_EN <= '1' when (RD_CNT = "00" and RD = '0') else '0'; 
2
WR_2_EN <= '1' when (RD_CNT = "01" and RD = '0') else '0';
3
WR_3_EN <= '1' when (RD_CNT = "10" and RD = '0') else '0';
4
5
6
D <=                 X_DATA(7 downto 0)  when WR_1_EN = '1' else (others =>
7
'Z');
8
D <=                 Y_DATA(7 downto 0)  when WR_2_EN = '1' else (others =>
9
'Z');
10
D <= X_DATA(11 downto 8) & Y_DATA(11 downto 8) when WR_3_EN = '1'
11
else (others => 'Z');

Du willst anscheinend 3 verschiedene Signal auf den gleichen Datenbus D
legen.
Die korrekte Hardware (-Beschreibung) dazu ist zuerst ein Multiplexer,
der zwischen den Signalen auswählt, und dann der Tri-State Block
selbst.
1
-- Zuerst der Multiplexer 
2
with RD_CNT select
3
    OutputData <=
4
        X_DATA(7 downto 0) when "00",
5
        Y_DATA(7 downto 0) when "01",
6
        D <= X_DATA(11 downto 8) & Y_DATA(11 downto 8) when "10",
7
        "--------" when others;
8
9
-- Dann der Tri-State Buffer
10
D <= OutputData when WR_EN = '1' else (others => 'Z');

Wenn in diesem Fall das WR_EN Signal direkt von einem GTS Pin kommt,
dann sollte das GTS verwendet werden.
Grüße
Klaus

von Klaus F. (kfalser)


Lesenswert?

Nachtrag :
1
-- Dann der Tri-State Buffer
2
D <= OutputData when RD = '0' else (others => 'Z');

müßte funktionieren, wenn Du das RD Sigal auf einen GTS Pin legst.

Klaus

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.