Forum: FPGA, VHDL & Co. Hilfe beim Design Implementieren: Inputs nicht mappbar?


von holyfetzer (Gast)


Lesenswert?

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!!!

von Christian R. (supachris)


Lesenswert?

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.

von holyfetzer (Gast)


Lesenswert?

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

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


Lesenswert?

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... ;-)

von Michl (Gast)


Lesenswert?

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;

von holyfetzer (Gast)


Lesenswert?

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...

von Michl (Gast)


Lesenswert?

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!) ".

von Michl (Gast)


Lesenswert?

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?...

von Michl (Gast)


Lesenswert?

Vergiss es.... ich muss ins Bett. Das obige kannste streichen von mir. 
Hab "<" als "=" gelesen xD... Mea Culpa!

von Michl (Gast)


Lesenswert?

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...

von Michl (Gast)


Lesenswert?

Fehlerhaft angemeldete Libraries.

von Christian R. (supachris)


Lesenswert?

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.

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


Lesenswert?

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...

von holyfetzer (Gast)


Lesenswert?

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?

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


Lesenswert?

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"

von holyfetzer (Gast)


Lesenswert?

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.

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


Lesenswert?

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"

von Klaus F. (kfalser)


Lesenswert?

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...

von holyfetzer (Gast)


Lesenswert?

Ok, werd's mir merken ;-)

von Tschaebe (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.