Forum: FPGA, VHDL & Co. Modul erhält auf Grund der Architektur zwei Clocks, Lösung?


von Queck S. (Firma: Uni) (kiigass)


Lesenswert?

Hi Leute

ich hab ein Problem, was auf den ersten Blick trivial scheint (und es 
vllt auch ist). Ich habe drei Module: A,B,C. A und B binden jeweils C 
ein und reichen das Clocksignal, welches sie von außen bekommen einfach 
an C weiter. Das Synthesetool sagt jetzt natürlich zu Recht, dass C zwei 
Clocks bekommt und bricht ab. Mein toller Plan war also einfach im Modul 
A das Clocksignal nicht weiter zu reichen an C. Aber das ist leider 
leichter gesagt als getan, denn wenn ich den Port auf "open" setze (in 
der port map von A) ist das Synthesetool damit auch nicht einverstanden.

Hat jemand nen Vorschlag für mich? Vllt bin ich auch betriebsblind...

thx for help

von Marius W. (mw1987)


Lesenswert?

Ganz eindeutig ein Fehler in Zeile 42... Wenn du den behebst, dann 
sollte es funktionieren.

Gruß
Marius

von Der Weise (Gast)


Lesenswert?

wenn A und B jeweils C einbinden, ergibt das nicht zwei Instanzen von C, 
die jeweils einen Clock bekommen?

von Queck S. (Firma: Uni) (kiigass)


Lesenswert?

Für Marius
1
entity A is
2
  port(
3
    clk : in std_logic
4
  );
5
end A;
6
7
architecture Behavioral of A is
8
9
component C
10
  port (
11
    clk : in   STD_LOGIC
12
  );
13
end component;
14
15
begin
16
17
modulC : C
18
  port map(
19
    CLK =>  CLK
20
  );
1
entity B is
2
  port(
3
    clk : in std_logic
4
  );
5
end B;
6
7
architecture Behavioral of B is
8
9
component C
10
  port (
11
    clk : in   STD_LOGIC
12
  );
13
end component;
14
15
begin
16
17
modulC : C
18
  port map(
19
    CLK =>  CLK
20
  );

@ Der Weise: Das weiß ich nicht genau, aber ich denke dass das nicht so 
ist.

von Winfried J. (Firma: Nisch-Aufzüge) (winne) Benutzerseite


Lesenswert?

vielleicht sollte C zwei unabhängig gepufferte "Ports" bedienen, dann 
kann es auch zwei unabhänige Clocks und Datenbusse verazten.

Namaste

von Queck S. (Firma: Uni) (kiigass)


Lesenswert?

Winfried J. schrieb:
> vielleicht sollte C zwei unabhängig gepufferte "Ports" bedienen, dann
> kann es auch zwei unabhänige Clocks und Datenbusse verazten.
>
> Namaste

Wie genau meinst du das?

von Marius W. (mw1987)


Lesenswert?

So wie du das oben beschrieben hast, bekommst du definitiv zwei 
Instanzen von C. Eine in A und eine in B. Wenn du nur eine Instanz haben 
möchtest, musst du ein Toplevel-VHDL anlegen, das 1 x A, 1 x B und 1 x C 
instanziert.

Gruß
Marius

von Queck S. (Firma: Uni) (kiigass)


Lesenswert?

Marius Wensing schrieb:
> So wie du das oben beschrieben hast, bekommst du definitiv zwei
> Instanzen von C. Eine in A und eine in B. Wenn du nur eine Instanz haben
> möchtest, musst du ein Toplevel-VHDL anlegen, das 1 x A, 1 x B und 1 x C
> instanziert.
>
> Gruß
> Marius

Danke, dann bin ich schonmal nen Meter schlauer was das angeht. Aber das 
erklärt ja noch nicht, warum denn das Syntesetool die Meldung ausgibt:
"Xst:1534 - Sequential logic for node <dd> appears to be controlled by 
multiple clocks."

dd ist ein Signal im Modul C

von Marius W. (mw1987)


Lesenswert?

Lad doch einfach den kompletten Source-Code hier hoch... Nicht nur ein 
"Schema" wie oben. Sonst wird das hier ein herumgestocher ohne Ende und 
darauf habe ich keine Lust.

Gruß
Marius

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Das Problem liegt nicht in den geposteten Zeilen.

Queck Silber schrieb:
> dd ist ein Signal im Modul C
Dann zeig doch mal, was mit diesem Signal D im Modul C alles gemacht 
wird...

von Queck S. (Firma: Uni) (kiigass)


Lesenswert?

Marius Wensing schrieb:
> Lad doch einfach den kompletten Source-Code hier hoch... Nicht nur ein
> "Schema" wie oben. Sonst wird das hier ein herumgestocher ohne Ende und
> darauf habe ich keine Lust.
>
> Gruß
> Marius

Das geht leider nicht aus zwei Gründen: Zum einen handelt es sich 
insgesamt um über 3000 Zeilen Code, zum anderen darf ich einige Teile 
davon nicht veröffentlichen. Aber ich glaube, dass der Inhalt der Module 
für das aktuelle Problem auch keine wirkliche Rolle spielt, denn das 
Clock-Signal wird ja nur von oben durchgereicht (wie im Schema oben). 
Die Architektur ist so, dass es ein übergeordnetes Modul gibt, welches 
sowohl A und B einbindet und das CLK an beide weiter gibt, dann kommt C. 
Also eine Art Rauten-Architektur. Beim Modul C handelt es sich um dieses 
hier: http://www.lothar-miller.de/s9y/archives/29-Division-in-VHDL.html

von Winfried J. (Firma: Nisch-Aufzüge) (winne) Benutzerseite


Lesenswert?

Nun, ich würde es so machen wie ich es auch mit diskreten Baugruppen 
machen würde. In VHDL kenne ich mich nicht aus, aber das Problem besteht 
immer wo verschieden Getaktete Systeme verbunden werden müssen. Und da 
helfen FiFo's(puffer) und separate Ports(Schnittstellen). Wie du das in 
VHDL umsetzt, das sollte eine schematische Übung sein.

Namaste

von Marius W. (mw1987)


Lesenswert?

Ohne konkreten Code wird dir hier niemand helfen können. Kannst du 
wenigstens die Dateien für A, B und C und deren Toplevel-Design 
hochladen? Zur Not gehts auch mit A und B als "Black-Box". Aber je mehr 
Source-Code du uns zur Verfügung stellst, umso eher kann dir hier 
geholfen werden.

Gruß
Marius

von Queck S. (Firma: Uni) (kiigass)


Lesenswert?

Marius Wensing schrieb:
> Ohne konkreten Code wird dir hier niemand helfen können. Kannst du
> wenigstens die Dateien für A, B und C und deren Toplevel-Design
> hochladen? Zur Not gehts auch mit A und B als "Black-Box". Aber je mehr
> Source-Code du uns zur Verfügung stellst, umso eher kann dir hier
> geholfen werden.
>
> Gruß
> Marius

ok ich werd das morgen früh mal abklären, was ich veröffentlichen darf. 
Vllt kommen wir dann ja weiter. Danke euch schonmal bis hierhin für eure 
Hilfsbereitschaft.

von Klaus (Gast)


Lesenswert?

Queck Silber schrieb:
> dd ist ein Signal im Modul C

Zeig doch einfach mal genau den Prozess, von dem das Signal dd getrieben 
wird. Das sollte wahrscheinlich reichen um den Fehler zu finden.

von Queck S. (Firma: Uni) (kiigass)


Lesenswert?

Ok gute Neuigkeiten der Chef sagt ich darf den ganzen Projektzweig 
veröffentlichen oO nungut...


Hier ist er:
http://www.darkenfalls.de/fileadmin/ECCv12.zip

Das Problem tritt auf, wenn man versucht das main-Modul zu 
synthetisieren. Ich nutze das Xilinx ISE WebPack. Das ganze soll am Ende 
auf einen Spartan3E.

Grundsätzlich geht es in diesem Zweig um Ver-/Entschlüsselung mit 
elliptischen Kurven und Diffi-Hellmann-Schlüsselaustausch. Später soll 
das Ganze vllt noch auf El-Gamal gebürstet werden. Momentan befindet 
sich das aber noch in der Entwicklung und ist deshalb an einigen Stellen 
etwas chaotisch und im Ganzen so gut wie gar nicht dokumentiert.

Ich bin natürlich offen für Vorschläge, wenn jemandem sonst noch was 
auffällt, außer dem hier geposteten Problem/Thema.

PS: Die Simulation funktioniert an sich. Dort gibt es nur ein Problem: 
Das Eingangssignal von dem Euklid-Modul wird an einigen Stellen (bzw 
einige Bits davon) "X".

Danke für eure Geduld

PPS: die Module die ich oben mit A, B und C bezeichnet habe sind hier: 
point_addition, point_doubling und divider2

von Klaus (Gast)


Lesenswert?

1
   process 
2
   variable diff : unsigned(b-1 downto 0);
3
   begin
4
      wait until rising_edge(clk);
5
      ...
6
      if rst = '1' then  
7
      ...
8
      elsif clk'event and clk = '1' then


Ähm, warum fragst dort 2 mal das Signal clk auf die Flanke ab? Nimm mal 
das wait until rising_edge(ckl);  raus.

Und nebenbei: if clk'event and clk = '1' then  kannst du dann auch 
gleich schöner, nämlich so wie in der anderen Zeile als if 
rising_edge(clk) then  schreiben.

von Queck S. (Firma: Uni) (kiigass)


Lesenswert?

meines Wissens nach ist die Zeile
1
wait until rising_edge(clk);

für den Simulator und die Zeile
1
if clk'event and clk = '1' then

für das Synthesewerkzeug. Ich lasse mich gerne eines besseren belehren, 
aber ich habe persönlich die Erfahrung gemacht, dass der Simulator 
meckert wenn die erste Zeile fehlt und das Synthesetool wenn die zweite 
fehlt. Nur so wie es oben steht geht beides ohne Fehlermeldung. Aber wie 
gesagt, ich lass mich gerne eines besseren belehren, denn du hast 
natürlich recht, dass es doppelt (redundant) ist.

PS: Ich habs grad nochmal probiert: Wenn ich die erste Zeile weglasse, 
macht der Simulator gar nichts mehr (ich nehme an er hängt sich in einer 
Endlosschleife auf). Die Umformulierung von "if CLK'event and CLK ='1' 
then" nach "if rising_edge(clk) then" klappt problemlos.

von Klaus (Gast)


Lesenswert?

Die beiden Zeilen sind nicht redundant (im Sinne, dass die zweite 
eigentlich unwirksam weil doppelt ist) sondern es sind tatsächlich 2 
Taktflangenabfragen die dann den Prozess steuern. Und das bemängelt der 
Synthesizer dann zu recht, wenn soetwas gibt es in einem FPGA nicht.

Beide Zeilen funktionieren sowohl für die simulation, als auch für die 
Synthese.

Aber: bei einem Process der nur ein wait until am anfang hat, darf die 
sensitivity list fehlen, bei der anderen variante nicht! Wenn du also 
einen asynchonen Reset in die ursprüngliche Implementierung von loathar 
einfügen möchtest, kannst du das wait until durch
1
if rst = '1' then  
2
      ...
3
elsif rising_edge(clk) then

ersetzten. Dann musst du aber eine sensitivity list angeben:
1
process(clk, rst)

von Queck S. (Firma: Uni) (kiigass)


Lesenswert?

Das heißt dann, dass wenn ich einen synchronen Reset möchte, ich 
eigentlich die Zeile mit dem
1
elsif clk'event and clk = '1' then
 in
1
else
 umwandeln kann? Denn dann würde ja immer noch die erste Zeile den 
Prozess takten, die if-Abfrage würde Reset prüfen und je nach Zustand 
einen der beiden Zweige durchlaufen. Das probier ich gleich mal aus.

von Klaus (Gast)


Lesenswert?

Ja, für einen synchronen Reset dann einfach else schreiben und alles 
andere so lassen.

von Queck S. (Firma: Uni) (kiigass)


Lesenswert?

wunderbar, ich glaube es ist gelöst, ich habs grad umgesetzt und es 
lässt sich sowohl simulieren als auch synthetisieren.

Danke dir!

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Queck Silber schrieb:
> meines Wissens nach ist die Zeile
> wait until rising_edge(clk);
> für den Simulator und die Zeile
> if clk'event and clk = '1' then
> für das Synthesewerkzeug
Tja, so ist das, wenn man ungefragt Zeug zusammenkopiert... :-P
Und ich dachte schon, in meiner Divisionroutine wäre da noch ein Fehler.

Zum Hintergrund:
http://www.lothar-miller.de/s9y/archives/16-Takt-im-Prozess.html

von Queck S. (Firma: Uni) (kiigass)


Lesenswert?

stimmt, aber dem Dividierer fehlte noch ein Reset.^^

Außerdem würde mich interessieren ob man den auch für signed Operanden 
umschreiben kann.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Queck Silber schrieb:
> stimmt, aber dem Dividierer fehlte noch ein Reset.^^
LOL...
Glaube ich nicht, dass ein Dividierer einen Reset braucht. Niemals. 
Bestenfalls der Entwickler und die Buchautoren der letzten 20 Jahre 
meinen das.... :-)

Dazu auch das Xilinx WP272 und ähnliche.

> Außerdem würde mich interessieren ob man den auch für signed Operanden
> umschreiben kann.
Sicher.

von Queck S. (Firma: Uni) (kiigass)


Lesenswert?

Ich hab mich missverständlich ausgedrückt, ich brauche einen Reset an 
dem Dividierer, weil ich sonst nicht wüsste wie ich das machen könnte. 
Ich stand dem Problem gegenüber, dass der Dividierer noch am Arbeiten 
war, ich aber nicht warten wollte bis er fertig ist. Also brauchte ich 
eine Möglichkeit ihn zurück zu setzen.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Queck Silber schrieb:
> Also brauchte ich eine Möglichkeit ihn zurück zu setzen.
Das ist in diesem Fall nur irgendein Signal das von aussen kommt und 
dann die FSM auf den IDLE-Zustand überführt. Mit einem Reset (im 
landläufigen Sinn) hat das eigentlich nichts zu tun.

von Queck S. (Firma: Uni) (kiigass)


Lesenswert?

ja da gebe ich dir Recht, weil die Initialisierungen ja auch sowie so in 
den ersten Zuständen gemacht werden.

Mein Problem war, dass ich nicht genau feststellen konnte in welchem 
Zustand der Divider grade ist (von außen), dh sollte er nicht in "idle" 
sein und ich gebe von außen (einen Takt lang) Daten drauf und setze 
"start" auf 1, dann passiert (im Divider) überhaupt nichts. Wenn ich 
dann darauf warte, dass "busy" auf 0 geht bekomme ich zwar ein Ergebnis, 
aber unter Umständen nicht das was ich erwarte. Wie würdest du das 
lösen?

von Duke Scarring (Gast)


Lesenswert?

Ich würde mir das not IDLE (= busy) nach außen führen. Das kannst Du 
dann in einer passenden State-Machine verwenden.

Duke

von Queck S. (Firma: Uni) (kiigass)


Lesenswert?

Das funktioniert nicht so ohne weiteres, weil "busy" nicht initalisiert 
= 'U' ist, solange "start" noch nie 1 war

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Dann schreib das hin:
1
    busy      : out  STD_LOGIC := '0';

von Queck S. (Firma: Uni) (kiigass)


Lesenswert?

ich habs so ähnlich gemacht, es funktioniert an sich auch.
1
when idle => 
2
   if (start='1') then 
3
      z <= prepare; 
4
      busy <= '1';
5
   else 
6
      busy <= '0';
7
   end if;
(so btw: die Defaultwerte wie du, Lothar, ihn oben angegeben hast, 
gelten die auch für die Synthese?)

Was ich speziell tue ist folgendes: Im übergeordneten Modul habe ich 
eine Konstruktion:
1
...
2
when z1 =>
3
   if div_busy = '0' then
4
      div_start <= '1';
5
      folge_zustand <= z2;
6
   else
7
      div_start <= '0';
8
      folge_zustand <= z1;
9
   end if;
10
...

Ich warte also darauf, dass der Dividierer fertig ist und starte ihn 
dann neu, sollte er beschäftigt sein. Wenn er sowie so grade nichts zu 
tun hat wird er direkt gestartet. Das funktioniert auch, aber 
leider/offensichtlich ist diese Methode deutlich langsamer als den 
Divider mit dem von mir eingefügten Reset "zurück zu setzen" (Aufs Ganze 
bezogen ca. Faktor 4).

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Queck Silber schrieb:
> (so btw: die Defaultwerte wie du, Lothar, ihn oben angegeben hast,
> gelten die auch für die Synthese?)
Wenn der jeweilige Port ein Flipflop ist (getaktete Übergabe), dann ja.

Queck Silber schrieb:
> den Divider mit dem von mir eingefügten Reset "zurück zu setzen"
Warum macht der Core denn gerade was, wenn du das so einfach abbrechen 
kannst. Dann ist doch die aktuelle Berechnung unnötig...   :-/

von Queck S. (Firma: Uni) (kiigass)


Lesenswert?

Lothar Miller schrieb:
> Warum macht der Core denn gerade was, wenn du das so einfach abbrechen
> kannst. Dann ist doch die aktuelle Berechnung unnötig...   :-/

Das liegt daran, dass dort mehrere Prozesse laufen, die zum Teil im 
Kreis laufen. Einer von denen hatte diesen Divider gestartet, ohne dass 
ich es eigentlich wollte. Sicherlich hätte ich den Prozess auch einfach 
abstellen können mit einem CE, aber ich hatte mich für diese Option 
entschieden, weil sie mir in dem Moment einfacher erschien und auch 
immer noch tut. Denn das Abstellen der anderen Prozesse würde das 
Problem mit sich bringen, dass ich an jeder Stelle, an der dieser 
verwendet werden soll ihn wieder einschalten müsste. So schmeiß ich 
einfach die anderen Prozesse die grade nicht dran sind einfach raus und 
reiße die Kontrolle an mich. Dazu muss man sagen, dass der gesamte 
Ablauf der Berechnungen eher sequenziell ist, während die Module 
natürlich parallel laufen. Ich habe also alle Module laufen, die 
fröhlich ihre Berechnungen machen, aber nur ein "aktives" welches grade 
mit den "richtigen" Daten rechnet und wo mich deshalb auch das Ergebnis 
interessiert. Deshalb darf dieses aktive Modul den anderen dann einfach 
die Ressourcen wegnehmen.

von Jimbo (Gast)


Lesenswert?

>Ich lasse mich gerne eines besseren belehren,
>aber ich habe persönlich die Erfahrung gemacht, dass der Simulator
>meckert wenn die erste Zeile fehlt und das Synthesetool wenn die zweite
>fehlt.

Man merkt, dass es mit der Erfahrung weit her ist ;-)

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.