Hallo Community, ich bin wie viele vor mir auch schon relativ neu im Gebiet VHDL / FPGA. Ich versuche mir einen LED counter (ich weiß, gab's bestimmt schon tausendmal) zu basteln. Mein ISE-Projekt besteht aus 2 Files: - main.vhd - pins.ucf Erst mal das VHDL-File: entity MAIN is port( CLK: in std_logic; RESET: in std_logic; LED: out std_logic_vector(7 downto 0) ); end MAIN; --- MAIN architecture architecture BEHAVIORAL of MAIN is signal COUNTER: std_logic_vector (7 downto 0) := "00000000"; signal PRESCALER: std_logic_vector (20 downto 0) := "000000000000000000000"; begin --- COUNTER process COUNTER_PROCESS:process(CLK, RESET) begin if rising_edge(CLK) and CLK = '1' then if RESET = '1' then PRESCALER <= (others => '0'); COUNTER <= (others => '0'); elsif PRESCALER < "10111110101111000010000000" then PRESCALER <= PRESCALER + 1; else PRESCALER <= (others => '0'); COUNTER <= COUNTER + 1; end if; end if; end process; LED <= COUNTER; end BEHAVIORAL; Nun das UCF: NET "CLK" LOC = "E12" | IOSTANDARD = LVCMOS33 | PERIOD = 20.000 ; ######################################################################## ###### # Discrete Indicators (LED) ######################################################################## ###### NET "LED<0>" LOC = "R20" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "LED<1>" LOC = "T19" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "LED<2>" LOC = "U20" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "LED<3>" LOC = "U19" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "LED<4>" LOC = "V19" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "LED<5>" LOC = "V20" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "LED<6>" LOC = "Y22" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "LED<7>" LOC = "W21" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "RESET" LOC = "T16" | IOSTANDARD = LVCMOS33 | PULLDOWN ; Beim Implementierungsprozess kommen immer folgende Warnungen: WARNING:PhysDesignRules:367 - The signal <CLK_IBUF> is incomplete. The signal does not drive any load pins in the design. WARNING:PhysDesignRules:367 - The signal <RESET_IBUF> is incomplete. The signal does not drive any load pins in the design. WARNING:Par:288 - The signal CLK_IBUF has no load. PAR will not attempt to route this signal. WARNING:Par:288 - The signal RESET_IBUF has no load. PAR will not attempt to route this signal. WARNING:Par:283 - There are 2 loadless signals in this design. This design will cause Bitgen to issue DRC warnings. Ich habe schon ewig danach gegoogelt, aber nichts gefunden, was ich bisher meinem Problem zuordnen könnte. Wie gesagt, bin Anfänger :D Könnte mir jemand helfen, dieses Problem zu verstehen? Vielen Dank im Voraus!!!
holyfetzer schrieb: > if rising_edge(CLK) and CLK = '1' then Ui....copy-paste Fehler? Hast du das mal simuliert? Oder zimindest mal versucht, dir vorzustellen, wie ein Signal aussieht, das High ist und gleichzeitig eine Low-High Flanke hat? Ich vermute der optimiert alles weg, weil die Bedingung eh niemals erfüllt ist.
Ich muss mich korrigieren, es heißt natürlich nur if rising_edge(CLK) ich habe vorhon das geändert und so wie ich es gepostet habe ist es nicht richtig. ------------------------------------------------------------------------ - --- MAIN architecture architecture BEHAVIORAL of MAIN is signal COUNTER: std_logic_vector (7 downto 0) := "00000000"; signal PRESCALER: std_logic_vector (20 downto 0) := "000000000000000000000"; begin --- COUNTER process COUNTER_PROCESS:process(CLK, RESET) begin if rising_edge(CLK) then if RESET = '1' then PRESCALER <= (others => '0'); COUNTER <= (others => '0'); elsif PRESCALER < "10111110101111000010000000" then PRESCALER <= PRESCALER + 1; else PRESCALER <= (others => '0'); COUNTER <= COUNTER + 1; end if; end if; end process; LED <= COUNTER; end BEHAVIORAL; ------------------------------------------------------------------------ - Aber das Problem bleibt bestehen Und nein ich habe es noch nicht getestet, mangels HW diese Woche. Aber ich will nächste Woche, wenn ich anfange nicht blind irgendwas machen. Trotzdem wundert mich diese Meldung. Ich kann sie halt nicht interpretieren
Christian R. schrieb: >> if rising_edge(CLK) and CLK = '1' then > Ui....copy-paste Fehler? Hast du das mal simuliert? Halb so schlimm, im rising_edge steht ..and CLK='1'.. eh schon mit drin. Dann steht da eben ..and CLK='1' and CLK='1'.. Das ändert laut Boolscher Algebra nichts am Ergebnis... ;-)
Haste den Reset extra synchron gemacht? Eigentlich sollte ein Reset das einzige Signal sein, dass asynchron sein darf. Bei dir müsste es dann lauten: --- COUNTER process COUNTER_PROCESS:process(CLK, RESET) begin if RESET = '1' then PRESCALER <= (others => '0'); COUNTER <= (others => '0'); elsif rising_edge(CLK) then if PRESCALER < "10111110101111000010000000" then PRESCALER <= PRESCALER + 1; else PRESCALER <= (others => '0'); COUNTER <= COUNTER + 1; end if; end if; end process;
Vielen Dank für den Support erstmal. Geändert hat das aber leider nicht. Meine Frage: Ist diese Meldung überhaupt schlimm? Ich meine es ist ja "nur" eine Warning...
Da fällt mir auf du schreibst: PRESCALER <= PRESCALER + 1; COUNTER <= COUNTER + 1; für std_logic_vector-Signale. Somit dürfte dein System Latches produzerien. Versuch es mal mit Variablen und den dementsprechenden Konvertierungen bei der Zuweisung auf "LED";) Siehe auch: http://www.mikrocontroller.net/articles/VHDL#Grundregeln_f.C3.BCr_synthetisierbaren_VHDL-Code Speziell: "Jedes Ausgangssignal muss in jedem if-Zweig einen von sich selbst verschiedenen Wert zugewiesen bekommen, damit keine Latches entstehen (mein_signal <= mein_signal; ist unzulässig!) ".
Und nochmal was: Wie soll sich dein PRESCALER-Wert ändern? Du erhöhst ihn nur wenn folgendes gilt: elsif PRESCALER < "10111110101111000010000000" then PRESCALER <= PRESCALER + 1; Aber wie soll der jemals diesen Binärwert erreichen, wenn du ihn nur unter dieser Bedingung inkrementierst?...
Vergiss es.... ich muss ins Bett. Das obige kannste streichen von mir. Hab "<" als "=" gelesen xD... Mea Culpa!
Das spuckt mir ModelSim Compile für dein System aus: ** Error: C:/MentorGraphics/HDS2010.2a/examples/hds_scratch/scratch_lib/hdl/asdf_a sdf.vhd(37): No feasible entries for infix operator "+". ** Error: C:/MentorGraphics/HDS2010.2a/examples/hds_scratch/scratch_lib/hdl/asdf_a sdf.vhd(37): Type error resolving infix expression "+" as type ieee.std_logic_1164.STD_LOGIC_VECTOR. ** Error: C:/MentorGraphics/HDS2010.2a/examples/hds_scratch/scratch_lib/hdl/asdf_a sdf.vhd(40): No feasible entries for infix operator "+". ** Error: C:/MentorGraphics/HDS2010.2a/examples/hds_scratch/scratch_lib/hdl/asdf_a sdf.vhd(40): Type error resolving infix expression "+" as type ieee.std_logic_1164.STD_LOGIC_VECTOR. ** Error: C:/MentorGraphics/HDS2010.2a/examples/hds_scratch/scratch_lib/hdl/asdf_a sdf.vhd(47): VHDL Compiler exiting Also jeweils die "+" Zuweisungen...
Lothar Miller schrieb: > Christian R. schrieb: >>> if rising_edge(CLK) and CLK = '1' then >> Ui....copy-paste Fehler? Hast du das mal simuliert? > Halb so schlimm, im rising_edge steht ..and CLK='1'.. eh schon mit > drin. Dann steht da eben ..and CLK='1' and CLK='1'.. > Das ändert laut Boolscher Algebra nichts am Ergebnis... ;-) Hm, natürlich richtig. War schon spät, da hatte ich erst mal angenommen, der könnte das eventuell wegoptimieren, hatte keine Lust mehr, das Ding mal schnell zu simulieren.
Michl schrieb: > Eigentlich sollte ein Reset das einzige Signal sein, dass asynchron sein > darf. Eigentlich sollte nicht mal ein Reset asynchron sein (denn asynchrone Signale können vom Timinganalyzer nicht bewertet werden!) Oder bestenfalls nach genauer Betrachtung der Zielplattform. Siehe z.B. den legendären Beitrag "Xilinx und die Resets" Wenn schon eine asynchrone Beschreibung, dann muss auf jeden Fall der Reset einsynchronisiert werden! Denn sonst wird das Deaktivieren des Resets interessant: ein paar Flipflops einer FSM sehen noch den Reset, die anderen sind schon bei der Arbeit. Ein ungünstiger Start in den Arbeitstag... http://www.lothar-miller.de/s9y/archives/64-State-Machine-mit-asynchronem-Eingang.html > Eigentlich sollte ein Reset das einzige Signal sein, dass asynchron sein > darf. Auch wenn es in fast allen Büchern so beschrieben ist, muss es nicht unbedingt stimmen...
Vielen Dank für die rege Diskussion. Aber leider bin ich der Lösung von meinem Problem (gefühlt) noch nicht näher gekommen. Ich habe mal den Code wie folgt geändert, mit dem Ziel die Takteilung und den Counter zu trennen: --- MAIN architecture architecture BEHAVIORAL of MAIN is signal SLOW_CLK : std_logic; signal COUNTER: std_logic_vector (7 downto 0) := "00000000"; signal CLK_DIVIDER: std_logic_vector (22 downto 0) := "00000000000000000000000"; begin --- Clock division CLK_DIVISION : PROCESS (CLK, CLK_DIVIDER) begin if (CLK = '1' and CLK'EVENT) then CLK_DIVIDER <= CLK_DIVIDER + 1; end if; SLOW_CLK <= CLK_DIVIDER(22); end process; --- COUNTER process COUNTER_PROCESS:process(SLOW_CLK, RESET, COUNTER) begin if RESET = '1' then COUNTER <= (others => '0'); else if (SLOW_CLK = '1' and SLOW_CLK'EVENT) then COUNTER <= COUNTER + 1; end if; end if; end process; end BEHAVIORAL ; Dies behebt die Warnungen wirklich. Aber was ist wirklich der Knackpunkt hierbei?
holyfetzer schrieb: > Aber was ist wirklich der Knackpunkt hierbei? Dass du offenbar die Antwortposts nicht gelesen und oder verstanden hast! Warum sollte man dir antworten, wenn du immer noch asynchrone Resets verwendest und vor allem immer noch mit std_logic rechnest? BTW: eine VHDL-Beschreibung fängt ganz oben an. Wie soll man wissen, als was dein std_logic_vector interpretiert wird, wenn man nicht weiß, welche Libs du verwendest? Siehe den Beitrag "IEEE.STD_LOGIC_ARITH.ALL obsolete" > if (CLK = '1' and CLK'EVENT) then > if (SLOW_CLK = '1' and SLOW_CLK'EVENT) then Und jetzt verwendest du auch noch einen abgeleiteten Takt. Mehr dazu im Beitrag "Re: Frequency divider Ausgang als Clock"
Sorry, wenn ich etwas unbeholfen rüberkomme. Es ist einfach nur so, dass am Anfang nicht alles automatisch logisch ist. Besonders, wenn man aus der Programmierecke kommt, wo eigentlich alles erst mal mehr oder weniger richtig ist, solange die Syntax und die abstrakte Verwendung stimmt :D Bei FPGAs muss man eben sehr viel mehr über (Programm-)Strukturen und Ansätze nachdenken, um etwas zu erreichen. Und ich möchte einfach die wichtigsten Ansätze und Hintergründe verstehen, um danach, wenn ich mit der HW arbeite, auch zu verstehen wieso etwas funktioniert (oder eben nicht funktioniert) und wo man nach Fehlern suchen muss. Es geht mir natürlich nicht primär darum, irgendwelche Lichtlein blinken zu sehen. Es geht ums Verstehen. Auch dieses Library-Wirrwarr ist natürlich etwas verwirrend zu Beginn. Ich frage mich, warum, obwohl doch offenbar Hersteller-abhängig, werden diese Packages sehr häufig trotzdem benutzt. Gerade IEEE.STD_LOGIC_ARITH ist doch (von mir gefühlt) mehr Regel als Ausnahme in allen möglichen Tutorials etc. Naja, also ich habe nochmal etwas gelesen und den Code dahingehend modifiziert, dass ich u.a. IEEE.STD_LOGIC_ARITH nicht mehr verwende. Teile dieses Ansatzes kommen von der Website von Lothar Miller. Auch dieses nicht so prickelnde Clock heruntertakten habe ich wieder entfernt. Den Reset habe ich nun mal komplett Clock-synchron eingeführt. Ich denke, dass dies der bessere Weg ist. library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity MAIN is Port ( CLK : in STD_LOGIC; RESET : in STD_LOGIC; LED : out STD_LOGIC_VECTOR (7 DOWNTO 0) ); end MAIN; architecture BEHAVIORAL of MAIN is signal C : integer range 0 to 24999999 := 0; -- 0,5s bei 50MHz fosc signal X : integer range 0 to 7 := 0; --- 8 bit value begin COUNTER : process(CLK) -- Clock process begin if (CLK = '1' and CLK'EVENT) then if (RESET = '1') then -- Synchroner Reset C <= 0; -- X <= 0; elsif (c<24999999) then -- 0…24999999 = 25000000 Takte = 1/2 Sekunde bei 50MHz C <= C+1; -- wenn kleiner: weiterzählen else -- wenn Zählerende erreicht: C <= 0; -- Zähler zurücksetzen X <= X+1; -- und Signal x hochählen end if; end if; end process; LED <= std_logic_vector(to_unsigned(X, LED'LENGTH));-- Signal x an LED ausgeben Zumindest jetzt bin ich erst mal Warning-frei geworden, was sich gut anfühlt.
holyfetzer schrieb: > Gerade IEEE.STD_LOGIC_ARITH ist doch (von mir gefühlt) mehr Regel als > Ausnahme in allen möglichen Tutorials etc. Ja, genauso wie der asynchrone Reset... Und sogar im von mir gern empfohlenen Buch steht noch son Zeuch vom letzten Jahrtausend drin. Siehe den Beitrag "Re: Verständnisproblem Xilinx XC9572 CPLD"
holyfetzer schrieb: > if (CLK = '1' and CLK'EVENT) then Jetzt solltest Du Dir nur noch die Verwendung von
1 | if rising_edge(CLK) then |
angewöhnen...
Im ursprünglichen Code ist der Prescaler 21 Bits breit, während der Vergleichswert (elsif PRESCALER < "10111110101111000010000000") 26 Bit breit ist, die Bedingung ist also vermutlich immer erfüllt und wird in der Synthese rausgekuerzt. Vielleicht war das das Problem?
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.