mikrocontroller.net

Forum: FPGA, VHDL & Co. Flankengesteuertes RS-FF in VHDL


Autor: Benedikt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich versuche schon seit ein paar Stunden flankengesteuert ein FF zu
setzen und zurückzusetzen:
Kommt eine High-Low Flanke von Signal A, soll dass FF gesetzt werden,
kommt eine Low-High Flanke von Signal B, soll es zurückgesetzt werden.

Aber leider komme ich mit der Triggerung auf die beiden Flanken nicht
weiter...

Autor: Kest (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
if a'event and a='1' then
  q <='1';
elsif b'event and b='0' then
  q <='0';
end if;

? Ist das das, was Du suchst?

Kest

Autor: Benedikt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, so habe ich es auch:

 if ale='0' and ale'event then
  ras <= '1';
 elsif En='1'  and En'event then
  ras <= '0';
 end if;

Allerdings kommt dann ein Fehler:

Signal ras cannot be synthesized, bad synchronous description.

Autor: Kest (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich vermute mal, dass da noch ein ELSE-Zeweig fehlt

 if ale='0' and ale'event then
  ras <= '1';
 elsif En='1'  and En'event then
  ras <= '0';
 else
  ras <= 'Z'; -- oder so?
 end if;

Kest

Autor: Benedikt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Auch nicht:
Signal ras cannot be synthesized, bad synchronous description.

Autor: Kest (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Womit synthetisierst Du?

Vielleicht doch 'event umschreiben? So wie:

if ale_old='1' and ale='0' then
 ale_old='0';
 ras <='1';

und so weiter?

Sonst weis ich auch nicht. Eigentlich sollte daraus etwas Kombinatorik
entstehen, aber damit kommt doch heutzutage jede Software klar, oder
etwa doch nicht? :-o

Kest

Autor: Benedikt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich verwende Xilinx ISE 6.3i und versuche das ganze in einen XC9536 zu
packen.

Autor: Kest (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Okay, etwas wird mir klar, Benedikt. Ist zwar nur eine Vermutung, aber
ich denke, ich bin da schon ziemlich nahe an der Lösung:
und zwar guck Dir die Struktur der Macrozellen an. Meistens haben sie
nur einen CLOCK Eingang. Man kann also nur ein Mal 'event nehmen...
keine Ahnung, ob ich mich jetzt verständlich ausdrücke. Versuch' mal
ohne Else, sondern einfach mit if's zu schreiben


 if ale='0' and ale'event then
  ras <= '1';
 end if;

 if En='1'  and En'event then
  ras <= '0';
 end if;


vielleicht klappt es so?

Kest

Autor: Benedikt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein, so geht es auch nicht.

Alle Ideen die ich hatte, verstoßen gegen irgendeine VHDL Regel.

- 2 Events in einer if Schelife funktionieren nicht, da die Latches nur
1 Clock Eingang haben.
- 2 getrennte ifs gehen nicht, da man nicht einem Signal an zwei
getrennten Stellen einen Wert zuweisen kann. Die Software weiß nämlich
nicht, ob nicht beide ifs gleichzeitig wahr sein können.
- Das mit dem Hilfssignal läuft auf eine der beiden zuvor genannten
Verstöße zu, denn ale_old muss irgendwie auch wieder auf 1 gesetzt
werden.
Wenn ich solch eine Schaltung per Hand aufbauen würde, würde ich ein
RS-FF nehmen, und die beiden Signale differenzieren, um kurze Peaks zu
erzeugen mit denen das FF gesetzt bzw. zurückgesetzt wird. Aber leider
geht das hier nicht so einfach, und ein digitales Monoflop das mit
Hilfe einem Takt einen Peak erzeugt wäre etwas aufwenig...

Autor: T.M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In einem Prozess darf nur 1 Clock signal mit 'Event abgefragt
werden.Alles andere führt zu obiger Fehlermeldung.

Autor: T.M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
process(B)
begin
  if B'event and B ='0' then
    B_intern <= '1'
  end if;
end process;

process(A, B_intern)
begin
  if B_intern = '1' then
    ras <= '0';
  elsif A'event and A = '1' then
    ras <= '1';
  end if;
end process;

probier es mal so

Autor: FPGA-User (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Benedikt

FFs die auf 2 Taktflanken arbeiten, gibts nur im CoolRunner II.

Versuch doch mal stattdessen die Funktion so zu beschreiben,
dass Du mit 1 Flanke und einem asynchronen Set- oder Reset-Signal
auskommst - geht das ?
Ansonsten wird nichts übrigbleiben, als die Signale einzutakten
und die übliche Flankenerkennung mit 2 FFs zu machen.

Autor: Henrik K. (henrik)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Man kann das nicht synthetisieren, weil man sich für die steigende oder
fallende Flanke entscheiden muß! Ein (einzelnes) FF das auf beide
Flanken reagiert gibt es auch nicht zu kaufen. Da musst man sich schon
eine etwas komplexere Logik einfallen lassen.
Im Anhang findest du die Schematik eines Vorschlags von mir. Aber
ACHTUNG: Diese Schaltung könnte sehr STÖRANFÄLLIG sein, da sie gezielt
Laufzeiten von Gattern ausnutzt! Ich empfehle dir Einschränkungen bei
deinen Anforderungen zu machen und etwas "stabileres" zu
programmieren!
Ich würde die Schltung NICHT einsetzen.

[VHDL]
entity SFF is
    Port ( A : in std_logic;
           B : in std_logic;
           Q : out std_logic
        );
end SFF;

architecture Behavioral of SFF is
Signal va      :std_logic;
Signal vb      :std_logic;
Signal res_vab  :std_logic;
begin

Main: Process (A,B, va, vb, res_vab)
begin

if (res_vab='0') then
  if  (A='0' and A'event) then
    va<='1' ;
  end if;
else
 va<='0';
end if;

if (res_vab='0') then
  if (B='1' and B'event) then
    vb<='1';
  end if;
else
 vb<='0';
end if;

res_vab<=vb;

Q<=va;

end Process Main;


end Behavioral;
[\VHDL]

Gruss Henrik

Autor: Henrik K. (henrik)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mal wieder 2 schneller...

Autor: T.M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mein Quelltext oben ist natürlich Quark. B_intern wird ja nie mehr
zurückgesetzt. Zu so später Stunde sollte ich wohl mein Gehirn nicht
mehr quälen ;-) Aber ich schliesse mich dem Vorschlag vom FPGA-User an,
dein Design so umzustellen, dass ein normales D-FF mit asynchr. Reset
eingesetzt werden kann. Lässt sich am besten handeln.

Grüße
T.M.

Autor: T.M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hätte dann doch ne Frage: Ich dachte immer, in einem Prozess ist nur
1 clocksignal erlaubt? Hendriks Code lässt sich aber einwandfrei
synthetisieren mit ISE... Hab ich da nen Verständnisproblem?

Grüße
T.M.

Autor: Benedikt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ich dachte immer, in einem Prozess ist nur 1 clocksignal erlaubt?

Erlaubt sind meherere, man sollte aber nur eines verwenden, da es
offiziell nicht funktionieren muss, es kann aber.

Autor: Benedikt (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Icb bechreibe mal für was ich das ganze brauche, vielleicht fällt
jemandem eine Lösung ein:

Das ganze ist ein DRAM Controller für einen AVR:
ALE dient als RAS Signal, aber leider bleibt dieses bis zum nächsten
Lesevorgang auf Low (was aber nicht sein darf, wegen dem precharge
Timing).
Jedenfalls möchte ich den Cyclus mit der Low High Flanke von RD\ oder
WR\ (bei mir schon als Enable zusammengefasst) wieder beenden.

Ich hab es auch nochmal als Bild angehängt: Das schwarze habe ich, das
rote suche ich.

Autor: FPGA-User (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Benedikt
warum nimmst Du nicht eine Statemachine, in der alle
benötigten Signale synchron vom Takt abgeleitet
werden ?
Bei den asynchronen Tricksereien handelst Du Dir Ärger
ein, wenn nicht alles 100 Pro durchdacht ist
(Timing bei versch. Temp. ...)

Autor: Benedikt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@FPGA-User

Wenn ich alles synchron mache, geht mir Wertvolle Zeit verloren. Das
Timing ist schon kritisch genug. Daher würde ich den Takt gerne auf das
ALE Signal beziehen, denn das gibt die Startbedingung vor und sollte so
schnell wie möglich verarbeitet werden.

Da ALE aus dem Takt abgeleitet wird, ist es leicht verzögert. Wenn ich
das jetzt wiederum mit dem takt synchronisiere habe ich zumindest eine
halbe Taktperiode veroren, (wodurch mir dann 25ns fehlen würden).

Autor: Henrik K. (henrik)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@T.M. : Das in einem Prozess nur ein clock-Signal erleubt ist, kenne ich
nur indem Zusammenhang, dass es bei der Simulation Probleme geben kann,
nicht aber bei der Hardware.
Vielleicht ist das für eine Simulation besser geeignet:
entity SFF is
    Port ( A : in std_logic;
           B : in std_logic;
           Q : out std_logic
        );
end SFF;

architecture Behavioral of SFF is
begin

Main: Process (A,B)
variable res_vab  : std_logic;
variable va     : std_logic;
variable vb     : std_logic;
begin

if (res_vab='0') then
  if  (A='0' and A'event) then
    va:='1' ;
  end if;
else
 va:='0';
end if;

if (res_vab='0') then
  if (B='1' and B'event) then
    vb:='1';
  end if;
else
 vb:='0';
end if;

res_vab:=vb;

Q<=va;

end Process Main;


end Behavioral;

(wird auf das Gleiche synthetisiert wie oben)
Wie schon gesagt: Weil die Funktion durch die Laufzeiten von Gattern
funktioniert, würde ich diesen Code NICHT verwenden.

Gruss Henrik

Autor: FPGA-User (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Henrik

würde ich auch nicht einsetzen, res_vab ist ein Spike,
bei dem nicht sicher ist ob er ausreicht, um va wirklich
rückzusetzen.

Folgende Idee :
Das Reset-Signal für vb wird nicht aus dem eigenen Ausgang
Q sondern von va abgeleitet !
d.h.:

- der Ausgang von vb geht auf den Clear-Eingang von va
- der Ausgang von va geht auf den Clear-Eingang von vb
  (jetzt aber Lo-Aktiv)

Ziel ist, dass vb selbst erst asynchron zurückgesetzt
wird, wenn va ebenfalls zurückgesetzt wurde .

Autor: Benedikt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe jetzt noch etwas rumprobiert, und kam zu diesem Code, der
zumindest in der Simulation das macht, was ich möchte:

if ale='1' then
  state<='0';
elsif iclk='1' and iclk'event then
  state <= '1';
 end if;

if (state='1') then
  transfer <= '1';
 elsif ale='0' and ale'event then
  transfer <= '0';
 end if;

Dabei sind iclk und ale die Eingangssignale und transfer der Ausgang.

Autor: FPGA-User (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hm, könnte gehen, sieht erstmal gut aus.

Autor: Benedikt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In der Praxis funktioniert es auch, aber leider hat das Ausgangssignal
etwa 20ns Verzögerung gegenüber einem anderen (das ebenfalls mit ale
geschaltet wird).

Kann man irgendwie im CPLD diese 20ns verschwenden ?

Autor: TobiFlex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich würde es so probieren:

if iclk='0' and iclk'event then
  ras_a <= NOT ale;
end if;

if iclk='1' and iclk'event then
  ras_b <= ras_a;
end if;

ras <= ras_a AND ras_b;

Kann sein, daß ich die VHDL-Syntax nicht richtig getroffen habe weil
ich meistens in AHDL arbeite.
Spikes dürften nicht auftreten, denn L in ras_a und ras_b überlappen
immerhin einen halben Takt.

Autor: TobiFlex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
oder besser so:
Ich würde es so probieren:

if iclk='1' and iclk'event then
  ras_a <= NOT ale;
  ras_b <= ras_a AND NOT ale;
end if;


ras <= ale AND ras_b;

Autor: TobiFlex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
if iclk='1' and iclk'event then
  ras_a <= NOT ale;
  ras_b <= ras_a AND NOT ale;
end if;


ras <= ale OR ras_b;
           ^^

Noch ein Fehler: hier muß OR statt AND stehen!

Autor: Benedikt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich versuche gerade irgendwie 10-20ns an Verzögerung in das 11bit breite
Adressensignal zu bekommen.
Dem FAQ von Xilinx nach geht das, aber bei mir irgendwie nicht...

http://www.xilinx.com/xlnx/xil_ans_display.jsp?iLa...


Hier mein Code:

attribute KEEP : string;
attribute KEEP of adress0, adress1, adress2 : signal is "TRUE";
  --keep buffer from being optimized out

process (adress0) begin    --Adress Mux Delay
adress1 <=adress0;
adress2 <=adress1;
adress <=adress2;
end process;

Was mache ich falsch ?
Was hat das :string bei dem ersten attribute zu bedeuten ?

Autor: FPGA-User (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Benedikt

schreib erstmal alle Signale in die Sensitivity-List Deines Prozesses:
process(adress0, adress1, adress2)

oder vergiss besser die asynchrone Variante, erst war die synchrone
20 ns zu langsam, jetzt willst Du wieder 20 ns Verzögerung
reinbringen.
Glaub mir, das sind genau die Designs, die irgendwann funktionieren,
und wenn mal die Temperatur steigt oder ein SDRAM andere Parameter
hat dann gibts bei 3 von hundert Zugriffen Bitfehler - wie willst
Du das in den Griff bekommen ?

Autor: Benedikt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn ich ein SDRAM ansteuern würde, wäre das ganze einfach, aber leider
steure ich ein normales DRAM an, und das ist leider asynchron...

Wenn ich es schaffe, alle Adressignale um mindestens 10ns zu verzögern,
dann liege ich mit dem Timing laut Datenblatt im grünen Bereich.
Abgesehen vom Beginn des RAS Signals (und der entsprechenden Adressen)
ist der Rest eigentlich unkritisch.

Mittlerweile habe ich es irgendwie geschafft die Buffer einzubauen.
Seltsamerweise hat ein Signal (Adress6) eine andere Verzögerung als der
Rest, obwohl es bei der Belegung (Makrozelle usw.) keine Besonderheiten
hat. Ohne Buffer hat jedes Signal 25ns.

Destination Pad ale Clock (edge) to Pad
adress<0> 42.000
adress<10> 42.000
adress<1> 42.000
adress<2> 42.000
adress<3> 42.000
adress<4> 42.000
adress<5> 42.000
adress<7> 42.000
adress<8> 42.000
adress<9> 42.000
adress<6> 34.500
ras 25.000

Für jedes Signal habe ich einen Buffer eingebaut:

my_buf : buf
port map (
i => adress0(0),
o => adress(0));

Autor: high_speed (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit einem Design, das auf Laufzeiten aufbaut, wirst du unweigerlich
scheitern.
Erhöhe deinen Grundtakt und leite davon deine nötigen Takte ab.

MfG
Holger

Autor: Benedikt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich muss jediglich ein Signal etwas verzögern, um die CPLD Laufzeiten zu
kompensieren und die erforderlichen 10ns Hold Zeit erreichen.
Der Rest vom Timing ist fest vorgegeben.

Mit einer Handvoll TTL ICs (Adressmultiplexer, Refreshzähler usw.) und
einer Delayline wurde sowas früher oft aufgebaut.

Autor: FPGA-User (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Benedikt

Nix für ungut, aber Holger hat recht, das Ding geht in die Hose
wenn Du Dich auf irgendwelche Delays verlässt.

Ich habe schone einige Memory-Interfaces gemacht, u.a. für NAND-
Flash, asyncrone RAMs, DDR-RAM, MMC/SD-Cards usw.,
aber immer die Adressen, Daten und Strobes synchron von einem
Takt abgeleitet, das hat sich super bewährt.
Du kannst das Timing genau nachvollziehen und der Timing-Analyzer
in der FPGA-Software liefert die richtigen Werte.
Außerdem ist dann garantiert, dass die Geschichte im ges.
Temp-Bereich und Betriebsspannungsbereich funktioniert.

Autor: Benedikt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK, ich habe jetzt einen größeren CPLD genommen, bin daher mit den Pins
etwas flexibler (beim kleinen hatte ich keine freien Pins mehr, weshalb
ein externer Takt unmöglich war).
Damit versuche icht jetzt noch ein letzes mal die asynchrone Version,
wenn das nix wird stelle ich auf synchron um.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.