Hey Leute. Ich bin ziemlicher Anfänger in VHDL und FPGA. Ich habe ein
Nexysw Board von Digilant und wollte mir nun mal einen einfachen
Zähler(finite_state_machine) bauen. es soll einen Asynchrone reset geben
um das ganze zu stoppen und auf den Zustando zu bringen wo keine Led
leuchtet. nach betätigen des start schalters sollen die 7 LED´s der
reihe nach durch leuchten.....also die Zustände hoch zählen.
Bei der synthese des Quellcodes kommen mehrere Warnungen:
Par:288 - The signal AR_IBUF has no load. PAR will not attempt to route
this signal.
WARNING:Par:288 - The signal clock_IBUF has no load. PAR will not
attempt to route this signal.
WARNING:Par:288 - The signal start_IBUF has no load. PAR will not
attempt to route this signal.
WARNING:Par:283 - There are 3 loadless signals in this design. This
design will cause Bitgen to issue DRC warnings.
Was mache ich Grundsätzlich falsch? wie gesagt, bin absoluter Beginner.
hier mein Quellcode
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity Projekt_1 is
Port ( led_1 : out STD_LOGIC;
led_2 : out STD_LOGIC;
led_3 : out STD_LOGIC;
led_4 : out STD_LOGIC;
led_5 : out STD_LOGIC;
led_6 : out STD_LOGIC;
led_7 : out STD_LOGIC;
AR : in STD_LOGIC;
start : in STD_LOGIC;
clock: in STD_LOGIC);
end Projekt_1;
architecture finite_state_machine of Projekt_1 is
signal state: STD_LOGIC_VECTOR(2 downto 0) ;
begin
process (AR,clock)
begin
if AR='1' then
state <= "000" ;
elsif rising_edge(clock) then
case state is
when "000" =>
if start = '1' then state <= "001" ;
--else state <="000" ;
end if;
when "001" => state <= "010" ; led_1 <='1';
when "010" => state <= "011" ; led_2 <='1';
when "011" => state <= "100" ; led_3 <='1';
when "100" => state <= "101" ; led_4 <='1';
when "101" => state <= "110" ; led_5 <='1';
when "110" => state <= "111" ; led_6 <='1';
when "111" => state <= "001" ; led_7 <='1';
when others =>
end case;
end if;
end process;
end finite_state_machine;
LG marco
Hallo Marco,
die Warnungen bedeuten: Die drei Signale AR, clock und start wurden als
wirkungslos erkannt und herausoptimiert. Und Recht hat er, der Compiler!
Ein kleiner Hinweis (von VHDL-Anfänger zu VHDL-Anfänger): Wer schaltet
unter welcher Bedingung die led_x aus?
Grüße
Bernhard
@Marco
> Ein kleiner Hinweis (von VHDL-Anfänger zu VHDL-Anfänger):> Wer schaltet unter welcher Bedingung die led_x aus?
Berhard hat recht.
Warum beschreibst du jede LED einzeln. Das ist doch auch nur ein Vector.
Also:
1
entityProjekt_1is
2
Port(led:outSTD_LOGIC_VECTOR(7downto0);
3
AR:inSTD_LOGIC;
4
start:inSTD_LOGIC;
5
clock:inSTD_LOGIC);
6
endProjekt_1;
7
8
architecturesogehtsbesserofProjekt_1is
9
signalleds:STD_LOGIC_VECTOR(7downto0);
10
begin
11
process(AR,clock)
12
begin
13
ifAR='1'then-- nein, ICH würde einen asynchronen Reset nicht verwenden
14
leds<="00000000";-- auch wenn das so in allen Lehrbüchern steht ;-)
15
elsifrising_edge(clock)then
16
if(start='1')thenleds<="00000001";endif;-- wenn Start, dann Led einschalten
erstmal schönen Dank für die Antworten.
leds <= leds(6 downto 0) & led(7);
diese zeile verstehe ich nicht ganz. was passiert hier genau ?
Leider bin ich noch ein absoluter VHDL-anfänger und muss scheinbar
erstmal grundsätzlich umdenken. In den Vorlesungen für systementwürfe
lernen wir einen algorithmus wie man sequetielle Schaltungen einfach
realisieren kann. Wir beziehen uns dann immer auf Automatenstrukturen.
(ansteuerkombinatorik + Zustandspeicher + Ausgabekombinatorik) .
Ich habe leider noch keine Vorlesung zu VHDL gehört, deshalb versuche
ich das alles mit der Automatenstruktur zu machen. Aber das ist wohl in
VHDL nicht die effitienteste Variante oder? Bitte gebt mir mal einen
Tip?
> leds <= leds(6 downto 0) & led(7);
& ist der Verkettungsoperator: "0000" & "1111" ist "00001111"
Mit leds(6 downto 0) & led(7). nimmst du also das siebte Element links
weg und hängst es rechts wieder dran, alle anderen Elemente rutschen
dabei um eins nach links.
Hallo Marco,
in der Vorlesung hörst Du, was ein Automat ist. Die Realisierung, also
wie der Automat implementiert wird, das ist Sache der
Implementierungswerkzeuge. In diesem Fall erfolgt die Implementierung
also per VHDL in einem FPGA.
Das sind - grob gesprochen - unterschiedliche Abstraktionsebenen.
@ Jan , danke jetzt verstehe ich es .
@ Bernhard,
ja ich weis schon. Aber in der Hochschule stellen wir uns eine
sequentielle Aufgabe und lösen sie anhand eines gelernten Ablaufs.
1. Zusatandsgraph mit transitionen erstellen
2. Zustandsfolgetabelle aufstellen
3. mittels einer KT minimieren
4.... aus der Schaltfunktion zeichnen wir uns dann die Schaltung .
Meistens besteht diese aus einer zweistufigen Ansteuerkombinatorik,
einen DFF und einer zweistufigen Ausgabekombinatorik. Meistens ist das
vom Timing verhalten die beste Variante. Das Problem scheint mit VHDL zu
sein, dass ich die Schaltung so nicht eins zu eins nachbauen kann, weil
die Synthesewerkzeuge eh machen was sie wollen.
Nur was nützt mir der ganze Entwurfsaufwand, wenn ich es so nicht in
VHDL umsetzen kann ???
@ Marco
Es gibt durchaus die Möglichkeit, die Schaltung per Schematic-Editor zu
erzeugen. Beim Erstellen eines Source-Files über den "New Source" Dialog
lautet eine Auswahl "Schematic". Ich habe das allerdings noch nie so
gemacht.
Bernhard
@Marco,
dein erster Versuch war durchaus nicht so falsch.
Das Problem war nur, dass Deine Kode die einzelnen LEDs niemals
ausgeschalten hat. Deshalb hat der Compiler die einzelnen LEDs fest auf
'1' gelegt, den Rest der Schaltung als unnötig erachtet und
wegoptimiert.
Wenn Du deinen Kode so änderst, dass in jedem State die anderen LEDs
ausgeschalten werden, dann funktionierts.
Zusätzlich gibt es in deinem Kode eben ein paar
Verbesserungsmöglichkeiten.
Die wichtigste ist, dass man mehrere ähnliche Signale zu einem Vektor
zusammenfasst; also nicht LED_1, LED_2 ... usw. sondern LED als
STD_LOGIC_VECTOR(7 downto 0) deklariert.
Zur Vorgangsweise die Du in der Vorlesung lernst ist zu sagen, dass sie
im Prinzip schon richtig ist. Nur wird heutzutage vieles eben dem
Compiler überlassen. Zustandsgraphen wird man weiterhin verwenden, aber
die ganze Minimierung, die komplette Berechung der Kombinatorik macht
der Compiler. Das spart Zeit und Aufwand.
Klaus
Klaus Falser wrote
> @Marco,> dein erster Versuch war durchaus nicht so falsch.
ACK.
Ich wollte erst mal zeigen, dass sowas kürzer und übersichtlicher
beschrieben werden kann.
1
led_1:outSTD_LOGIC;
2
led_2:outSTD_LOGIC;
3
led_3:outSTD_LOGIC;
4
led_4:outSTD_LOGIC;
5
led_5:outSTD_LOGIC;
6
led_6:outSTD_LOGIC;
7
led_7:outSTD_LOGIC;
Und zwar mit
1
led:outSTD_LOGIC_VECTOR[7downto1];
War mein Versehen, übersehen zu haben, dass dein Vector nicht bei Led_0
beginnt. In der binären Welt ist die Zählweise ab D(0) und A(0) z.B. für
Adress- und Datenleitungen üblich.
Klaus Falser ist übrigens auch drauf reingefallen ;-)
> sondern LED als STD_LOGIC_VECTOR(7 downto 0) deklariert.> Nur wird heutzutage vieles eben dem Compiler überlassen.
Und das ist auch besser so, schliesslich ist es "nur" reine Rechen- und
Tabellenarbeit.
Ja, da hast du recht. In der digitalenwelt gehts immer bei Null los. das
sollte ich für die Übersicht bei den LED´s auch so machen.
Nochmals vielen Dank für eure Antworten. Jetzt bin ich ein ganzes Stück
weiter und kann mal voll durchstarten.
LG Marco