Hallo beisammen, zunächst vorneweg: bin ein FPGA und VHDL Newcomer, es könnten also einige blöde Fragen folgen :-). Ich habe gerade folgendes Verständnisproblem. In einer entity habe ich eine component eingebunden. Diese (selbstgebastelte) component besteht aus einem process, der zwei Binärzahlen dividiert. Da das leider eine recht sequenzielle Angelegenheit ist, gehe ich mal davon aus, dass das mit einem Takt nicht getan ist. Wenn ich jetzt in der entity dem divider auf die Eingänge Werte gebe, wie kann ich dann sichergehen, dass der Ausgang, den ich auslese auch zu den Eingabewerten gehört und nicht zu denen davor? Muss ich warten, bis sich der Ausgang ändert bzw. ein trigger signal mit einbauen? Wenn ja, wo ist dann der Unterschied zur Verwendung einer function oder procedure? Dann müsste die hardware quasi so synthetisiert werden, dass automatisch gewartet wird? Ach ja: Wie ist das dann, wenn ich "vorgefertigte" Komponenten, wie z.B. einen hardware multiplier (Spartan3E) einbinde. Muss/kann ich da warten? Hinter diese Timing-Sache steig ich noch nicht so ganz. Die sequenzielle Art zu Denken ist nur schwer zu verdrängen... Vielen Dank für jede Hilfe und jeden Hinweis. Gruß flo0815
> Da das leider eine > recht sequenzielle Angelegenheit ist, gehe ich mal davon aus, dass das > mit einem Takt nicht getan ist. Ich hoffe, du meinst damit: Du hast eine komplizierte ("tiefe") kombinatorische Logik beschrieben - also einen Haufen LUT's - deren Ausgänge direkt das Ergebnis in Abhängigkeit von den Eingängen ausgeben? Weil sequentiell kann ein FPGA nicht - diese LUT's, auch wenn davon viele hintereinander geschaltet sind, arbeiten ja im Prinzip alle parallel. >Wenn ich jetzt in der entity dem divider auf die Eingänge Werte gebe, >wie kann ich dann sichergehen, dass der Ausgang, den ich auslese auch zu >den Eingabewerten gehört und nicht zu denen davor? Vermutlich gibst du mit einer Taktflanke die Eingabedaten auf die Eingänge, und liest bei der nächsten Taktflanke das Ergebnis aus (jeweils mittels FlipFlops)? Dann macht die Toolchain das automatisch, vorausgesetzt, sie weiß, wie schnell der Takt ist, was in der UCF-Datei angegeben werden kann. Wenn deine kombinatorische Logik länger braucht um die Eingabe zu verarbeiten als ein Takt dauert, gibts Timing Errors am Ende des Place&Route bzw. in der Ausgabe der maximal möglichen Frequenz wird eine niedrigere angegeben. >Ach ja: Wie ist das dann, wenn ich "vorgefertigte" Komponenten, wie z.B. >einen hardware multiplier (Spartan3E) einbinde. Muss/kann ich da warten? Die Dinger sind sehr schnell, wie schnell steht im Datenblatt. Wenn du die inferierst - also einfach "c <= a * b;" schreibst, wird der Hardware-Block ja automagisch verwendet, und die Toolchain errechnet genau wie bei normaler Logik ob er schnell genug ist. Zur Division guggst du da: http://www.lothar-miller.de/s9y/categories/24-Division
Danke für die schnelle Antwort! >Ich hoffe, du meinst damit: Du hast eine komplizierte ("tiefe") >kombinatorische Logik beschrieben - also einen Haufen LUT's - deren >Ausgänge direkt das Ergebnis in Abhängigkeit von den Eingängen ausgeben? Das hoffe ich auch:
1 | entity DIVIDER is |
2 | --------------------------------------------------------------------
|
3 | Port ( Divisor_DIV : in STD_LOGIC_VECTOR(17 downto 0); |
4 | Dividend_DIV : in STD_LOGIC_VECTOR(17 downto 0); |
5 | Quotient_DIV : out STD_LOGIC_VECTOR(17 downto 0); |
6 | Start_DIV : in STD_LOGIC; |
7 | Finished_DIV : out STD_LOGIC); |
8 | end DIVIDER; |
9 | --------------------------------------------------------------------
|
10 | --------------------------------------------------------------------
|
11 | architecture Behavioral of DIVIDER is |
12 | |
13 | begin
|
14 | |
15 | Pdiv: process(Start_DIV) |
16 | |
17 | variable topbit : INTEGER RANGE -1 TO 17; |
18 | variable temp : STD_LOGIC_VECTOR (18 downto 0); |
19 | variable quot : STD_LOGIC_VECTOR (17 downto 0):=(others => '0'); |
20 | |
21 | begin
|
22 | |
23 | Finished_Div <= '0'; |
24 | |
25 | if Start_DIV='1' and Start_DIV'event then |
26 | |
27 | if Divisor_DIV > Dividend_DIV then |
28 | |
29 | Quotient_DIV <= (others => '0'); |
30 | |
31 | else
|
32 | |
33 | if divisor_DIV = "000000000000000000" then |
34 | |
35 | quotient_DIV <= "111111111111111111"; |
36 | |
37 | else
|
38 | |
39 | -- Find leftmost non-zero digit of divisor and save in variable topbit
|
40 | topbit := -1; |
41 | for i in 17 downto 0 loop |
42 | if divisor_DIV(i) = '1' then |
43 | topbit := i; |
44 | exit; |
45 | end if; |
46 | end loop; |
47 | |
48 | -- Do division algorithm.
|
49 | temp := "0"÷nd_DIV; |
50 | for i in 18-(topbit+1) downto 0 loop |
51 | if temp(topbit+i+1 downto i) >= "0"&divisor_DIV(topbit downto 0) then |
52 | temp(topbit+i+1 downto i) := (temp(topbit+i+1 downto i))-("0"&divisor_DIV(topbit downto 0)); |
53 | quot(i):='1'; |
54 | end if; |
55 | end loop; |
56 | |
57 | quotient_DIV <= quot; |
58 | |
59 | end if; |
60 | |
61 | end if; |
62 | |
63 | end if; |
64 | |
65 | Finished_DIV <= '1'; |
66 | |
67 | end process; |
68 | |
69 | end Behavioral; |
>Vermutlich gibst du mit einer Taktflanke die Eingabedaten auf die >Eingänge, und liest bei der nächsten Taktflanke das Ergebnis aus >(jeweils mittels FlipFlops)? Keine Ahnung, mach ich das? Ich setze die Signale Divisor_DIV und Dividend_DIV, danach setze ich Start_DIV<='1' und warte auf eine steigende Flanke auf Finished_DIV. Meine Frage ist, ob ich dieses triggern und warten auf Bestätigung immer machen muss, wenn ich auch tatsächlich das aktuelle Ergebnis und nicht das des letzten Durchgangs haben will. Danke übrigens für den Link. Werde mir das mal genauer anschauen. Gruß Flo
Ein Tipp an einen Anfänger: du brauchst keine for-Schleife. Sie macht etwas ganz anderes, als du erwartest... :-o >> Vermutlich gibst du mit einer Taktflanke die Eingabedaten ... > Keine Ahnung, mach ich das? Nein, schlimmer: du hast gar keinen Takt, sondern einen Dividierer kombinatorisch beschreiben... :-/ Geh einfach mal davon aus, dass du mit deiner Beschreibung einen riesengroßen kombinatorischen Multiplexer gebaut hast:
1 | for i in 18-(topbit+1) downto 0 loop |
2 | if temp(topbit+i+1 downto i) >= "0"&divisor_DIV(topbit downto 0) then |
3 | -- das ist ein Mega-Multiplexer
|
4 | temp(topbit+i+1 downto i) := (temp(topbit+i+1 downto i))-("0"&divisor_DIV(topbit downto 0)); |
5 | quot(i):='1'; |
6 | end if; |
7 | end loop; |
Das wird sich nicht in Hardware abbilden lassen:
1 | for i in 18-(topbit+1) downto 0 loop ... |
Denn du kannst für die Synthese nur einen statischen Bereich für die
for-Schleife angeben...
Du wirst diesen Dividierer also bestenfalls simulieren können. Manchen
reicht das ;-)
> Muss ich warten,...
Ja, das Ding ist unglaublich kompilziert (wenn du es mal übersetzt
bekommst), und die Synthese wird dir dafür dann eine recht lange
Laufzeit bescheinigen. Die mußt du abwarten.
Und: auf dein
1 | Finished_DIV <= '0'; |
2 | :
|
3 | Finished_DIV <= '1'; |
kannst du dich nicht verlassen. Die Synthese wird dieses Signal einfach fest auf '1' legen, weil die letzte Zuweisung im Prozess gewinnt (ein Prozess wird in der theoretischen Zeit 0 abgearbeitet).
Also, danke für die umfangreiche Antwort. Hast mir gerade mehr brauchbare Hinweise und v.a. Verständnishilfen gegeben, als ich in diversen Tutorials gefunden habe. Das mit der For-Schleife hab ich schon befürchtet. Ich war so frei, und habe nun den Divisions-Algorithmus von deiner Homepage benutzt. Das ist für eine Semesterarbeit. Wäre das für dich in Ordnung, wenn ich den Algorithmus benutze - selbstverständlich wissenschaftlich korrekt mit Quellen/Autorenangabe? Ich denke das mit dem Takt habe ich jetzt zumindest grob verstanden. Ein anderes Modul habe ich jetzt als FSM geschrieben. Da kann ich sauber auf den Dividierer warten und kann halbwegs nachvollziehen was passiert (oder nicht passiert :-)). Noch eine Frage: Gibt es empfehlenswerte Literatur, die eben auf die Synthetisierbarkeit eingeht? Über VHDL gibt es ja zeugs wie Sand am Meer, aber ich habe praktisch nichts mit praktischen Hinweisen für die Synthese gefunden. Nochmal vielen Dank. Gruß Flo
> Ich war so frei, und habe nun den Divisions-Algorithmus von deiner > Homepage benutzt. Das ist für eine Semesterarbeit. Wäre das für dich in > Ordnung, wenn ich den Algorithmus benutze - selbstverständlich > wissenschaftlich korrekt mit Quellen/Autorenangabe? Wie üblich eben... ;-) > Noch eine Frage: Gibt es empfehlenswerte Literatur, die eben auf die > Synthetisierbarkeit eingeht? VHDL-Synthese von Reichardt&Schwarz
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.