www.mikrocontroller.net

Forum: FPGA, VHDL & Co. zähler programmieren


Autor: Sandra T. (tsandra)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich bin neu in VHDL und muss ein zähler mit FPGA programmieren.ich muss 
ein VHDL-block erstellen, der die Takt-frequenz des FPGA-board(25Mhz)auf 
2hz herunter teilt und der ausgangssignal soll dabei zur kontrolle mit 
einer LED verknüpft werden,so dass die generierte frequenz sichtbar 
gemacht wird.ich habe schon etwas gemacht aber klappt nicht.ein freund 
meinte ich soll der cnt bis 28 zählen warun verstehe ich gar nicht.bitte 
helfen sie mir.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> ich habe schon etwas gemacht aber klappt nicht.
Ich könnte das schon schnell hinschreiben, aber damit wäre dir nicht 
unbedingt geholfen. Lass doch sehen, was du schon hast.

Ein Tipp:
Du brauchst einen Zähler, der von 0 bis (25000000/2)-1  zählt.
   signal counter : integer range 0 to (25000000/2)-1:
Der wird jetzt mit jedem Takt (25MHz) hochgezählt und beim Endwert 
wieder auf 0 gesetzt. Das MSB davon schließt du an die LED an. Fertig.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, ich habe den Anhang übersehen :-/
(Aber docx ist numal auch kein gängiges vhdl-Fileformat)

Ich verbessere mich:
Mit dem Integer ist die Rückwandlung des MSB etwas umständlich. 
Einfacher geht es mit dem Vektortyp unsigned aus der numeric_std Lib.
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
:
:
signal   count : unsigned (23 downto 0); -- (25000000/2)-1 
:
begin

    process(clk)
    begin
        if clk'event and clk = '1' then
            if  count < to_unsigned((25000000/2)-1,24)  then 
               count <= count + 1;
            else                                  
               count <= to_unsigned(0,24);
            end if;
        end if;
    end process;
    
    LED_1 <= count(23);
:
:

28 Bit scheinen mir etwas zuviel, damit kannst du auf fast 270Mio 
zählen, das ist nicht nötig.

Autor: Sandra T. (tsandra)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
danke ich hatte schon gedacht dass etwas nicht stimmt.ich versuche 
nochmal

Autor: Sandra T. (tsandra)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich gerade auch eine schnittstelle von der aufgabe bekommen und die 
lautet so:
eingänge: clk, reset_n(werden alle ausgangssignale auf null gesetz)
ausgänge: clk_out selbst erzeugte frequenz von 2hz
interne signal : count--zähler und clk_temp
es kann auch ein interne signal verwenden, dass die fpga-taktzyklen 
zählt.beim erreichen durch die vorgegeben frequenzen zu bestimmenden 
zeipunktes wird das interne signal "clk_temp" invertiert.dann wird 
clk_temp an das ausgangssignal clk_out übergeben welches mit der LED auf 
der board verknüpfen ist.

Autor: Schrotty (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn das Puls-Pausen Verhältnis des Ausgangstaktest 50% sein soll, würde 
ich einen Counter machen, der nicht 0,5s lang läuft, sondern 0,25s.
Dann jedesmal wenn der Counterwert erreicht ist, den Ausgang für die LED 
toggeln.

Autor: Sandra T. (tsandra)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
der muss aber 0,5s laufen.dieser aufgabe macht mich schon fertig ich 
weiss est nicht mehr weiter.wenn eine weiss wie das geht bitte hilfe.

Autor: Schrotty (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na wenn du deine LED für 0,25 sekunden an und dann für 0,25 sekunden aus 
hast, dann ist doch eine Periode 0,5s = 2 Hz lang.

Autor: Schrotty (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also mal ganz ausführlich:
2Hz ist eine Zeit von 0,5 Sekunden. In dieser Zeit muss das Signal 
einmal High und dann Low sein. Das heisst dann eine Periode.
Und wenn du willst, dass das Signal ein Rechteck ist, in dem die Zeit, 
wo es Hig und die Zeit, wo es low ist, gleich lang sind.. also sowas

--      ----      --                        --    ------    --
  |    |    |    |                            |  |      |  |
   ----      ----         und NICHT sowas:     --        --

dann ist doch die LED für 0,25s an und für 0,25s aus.

Und dann ist es doch recht naheliegend, einen Zähler zu bauen, der auf 
0,25s zählt, dann den Zustand der LED umdreht und wieder von vorne 
anfängt zu zählen usw..

Dein Zähler läuft mit 25MHz. Das heisst, er zählt alle 40ns um eins 
weiter.
Wie oft muss man um 40ns zählen, um auf 0,25 sekunden zu kommen?
--> 0,25s / 40 ns = 6 250 000. Und da der Zähler üblicherweise bei null 
anfängt, zählst auf 6 249 999.

Also: Ein Zähler, der von 0 auf 6249 999 zählt. Und immer, wenn er 
diesen Wert erreicht hat, schaltet er den Zustand der LED um, setzt sich 
selbst wieder auf 0 zurück und beginnt von vorne.

Ich hoff, ich konnte dir helfen.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So etwa:
(jetzt darfs wieder integer sein, das ist einfacher ;-)
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
:
:
signal   count : integer range 0 to (25000000/4)-1 := 0
signal   led : std_logic := '0';
:
begin

    process(clk)
    begin
        if rising_edge(clk) then
            if (count<(25000000/4)-1)  then 
               count <= count + 1;
            else                      
               led <= not led;            
               count <= 0;
            end if;
        end if;
    end process;
    
    LED_1 <= led;
:
:

Autor: Schrotty (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ganz genau so mein ich es, Lothar ;-)

Autor: Sandra T. (tsandra)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
so hatte ich eben geschrieben.

Autor: Sandra T. (tsandra)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich danke euch, dass ihr mir hilft

Autor: Schrotty (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
im Prinzip richtig, wenn ich das auf die Schnelle seh.
Allerdings geh ich davon aus, dass reset_n low-aktiv ist, also sollte 
auch die Abfrage auf '0' erfolgen.
Ausserdem glaub ich nicht, dass du count <= count + 1 schreiben kannst, 
wenn count std_logic_vector ist. Könnte sein, dass du dann den vollen 
Vektor addieren musst.

Also count <= count + "000000000000000000000000001";

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das geht:
> count <= count + '1';

EDIT:
6249999 sind bei mir x"5F5E0F"
Das korreliert gar nicht mit
"10111110101111000010000000"


So wird das mit dem Vektor nicht gehen:
signal   count    :   std_logic_vector(0 downto (25000000/2)-1 );
Du kannst nicht nur die Sahnehäubchen aus meinem Code naschen, nein das 
geht nicht ;-)
Versuch mal zu verstehen, was ich da hingeschrieben habe.

Und der Vergleich wäre so etwas übersichtlicher:
>  if count = "10111110101111000010000000" then
>  if count = "10" & x"FAF080" then
Aber wie oben schon gesagt: sowieso die falsche Zahl  :-(

Autor: Schrotty (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok, Lothar, das wusste ich auf die Schnelle nicht mehr.

Autor: Sandra T. (tsandra)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok der Reset_n ist auf low-aktiv hatte ich vergessen aber was mir noch 
stört ist diese übergabe weil mein count ist ein Vector und LED variable 
und habe gelesen das mann die so nicht konvertieren kann.
danke

Autor: Schrotty (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmm, Sandra, ich glaub, bei dir müssen wir ein wenig weiter ausholen.
Woher kommt die Aufgabe eigentlich, die du da lösen sollst? Also ist das 
im Rahmen einer Vorlesung oder Unterricht?

Ich schau mir grad deinen Code nochmal an. Also ich weiss nicht, wie du 
drauf kommst, dass LED ne Variable ist. Die LED ist ein Port vom Typ 
std_logic, so wie alle Signale auch, die du verwendest. Daher gibt es da 
keine Probleme bei irgendwelchen "Übergaben".

Ausserdem übergibst du ja eh nicht den Zähler an die LED, sondern du 
machst Folgendes (versuch dir das mal in Hardware mit Gattern aufgebaut 
vorzustellen):

Du nimmst einen Zähler. (count <= count + '1'). Diesen Zähler 
vergleichst du über einen Vergleicher mit deinem Grenzwert (if count = 
xxxxxx then...)
Wenn der Zähler also den Wert erreicht hat, dann wird der Zähler 
zurückgesetzt und gleichzeitig wird das SIGNAL clk_temp invertiert.
Du "übergibst" also nirgends irgendwelche Signale oder Variablen, 
sondern führst in Abhängigkeit des Zustandes des Zählers  Veränderungen 
am Signal clk_temp durch. Dieses Signal wird am Ende auf deinen Port 
LEDx verdrahtet.

uffz. ich hoff, das hat dir geholfen

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> versuch dir das mal in Hardware mit Gattern aufgebaut vorzustellen
Diese Abstraktion der Beschreibung ist überhaupt das wichtigste.

z.B. Hardwareentwicklung:
Ich zeichne einen Schaltplan, aber ich denke in ICs und Bauteilen.

entsprechend FPGA-Design:
Ich schreibe VHDL, aber ich denke in Gattern und Logik.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.