Forum: FPGA, VHDL & Co. Dezimalzahl auf 7 Segment Aneige


von Zack B. (zack)


Angehängte Dateien:

Lesenswert?

Hallo,
ich beschaeftige mich jetzt seit 2 Wochen mit FPGAs und hatte mir als 
kleines Beispiel Programm ueberlegt, eine Dezimalzahl auf der 7 
Segmentanzeige der Spartan3 Testboards auszugeben.

Jetzt weiss ich: Das war eine sehr gute Aufgabe um sehr sehr viel ueber 
FPGAs zu lernen...

Ich habe das Programm mal angehaengt, es waere schoen, wenn ihr da mal 
reinschauen koenntet um mit Tipps zu geben, was man optimieren koennte.

Hauptfunktion soll sein, eine Zahl von 0 bis 9999 anzuzeigen. Diese kann 
man mit den 4 Buttons um 1000, 100, 10 oder 1 erhoehen.

Dann bin ich mal gespannt, was ihr mir noch fuer Tipps geben koennt.

Danke!

von Falk B. (falk)


Lesenswert?

@ Zack B. (zack)

>Dann bin ich mal gespannt, was ihr mir noch fuer Tipps geben koennt.

- numberLocal ist unsinnig und überflüssig
- das mit der procedure setDigit im prozess SETDIGITS ist seher unüblich
- und bitte bei VHDL nicht anfangen case sensitiv zu denken, VHDL ist 
case INsensitiv
- das Rücksetzen von ctr ist überflüssig, der macht automatisch nen 
Overflow
- hast du dein Programm mal real ausprobiert? Kaum, denn shared 
Variables sind in der Synthese bei Xilinx nicht möglich (zumindest bei 
der alten 6.3 ISE) und hier auch vollkommen unnötig.
- deine binär-> BCD Wandlung sihet aufwändig aus, da kommt sicherlich ne 
Menge Logik zusammen.
- Lass das mit Variablen für Sachen wie BTN0old, sonst schiesst du dir 
mal schön ins Knie

MFG
Falk

von Joko (Gast)


Lesenswert?

Hi Zack,

  habe mir die 'Funktion nicht angesehen' - lediglich 'formale' Aspekte:

  1. std_logic_arith sollte nicht für neue Designs verwendet werden
        siehe http://dz.ee.ethz.ch/support/ic/vhdl/vhdlsources.en.html
         (ich weiß, jetzt wird eine ewig lange Diskussion beginnen)

  2. shared variable iVal0,[..]
          fang bloß nich damit an ! Laß den Unsinn mit
           "shared variable" (=> s. VHDL200x)

  3. variable im Prozeß
         kann man machen, aber so mancher hat sich schon gewundert,
         warum sich seine Schaltung anders verhält (in Simu + HW) als
         er dachte.
         Mein Rat: variablen nur da verwenden, wo unbedingt notwendig
         (bei der Simulation können sie u.U. schneller sein, da
           der Simulator keine Historie mitführen muß - gilt aber i.W.
           nur für große arrays)

  3. Sync reset
        a) für FPGAs SEHR GUT !!!
            (wußtet ihr eigentlich, daß die Xilinx-Tools einen 
asynchronen
             Reset-Pfad default-mäßig nicht checken ? So manche
             Statemachine hat sich deshalb schon 'verlaufen', weil
             beim Loslassen des Resets EIN FlipFlop schon in den 
nächsten
             Zustand sprang, währen ein ZWEITES noch im Reset 'hing')
        b) bei ASICs müßten wir drüber diskutieren

Gruß
Jochen

von Stefan W. (wswbln)


Lesenswert?

Ich muss zugeben, dass ich Dein "Programm" noch gar nicht angesehen 
habe, aber alleine die Verwendung des Begriffes "Programm" für eine 
FPGA-Konfiguration liess mich schon vermuten, dass jede Menge solcher 
Punkte wie Falk und Jochen auflisten bei Dir drin sein dürften....

Tröste Dich: a) aller Anfang ist schwer und b) Du bist weder der erste, 
noch wirst Du der letzte sein, der mit der "Hardware-Denke" bei FPGA und 
& Co so seine Probleme hat. Siehe diverse andere Threads hier (z.B. 
"Programm für CPLD zu gross"...)

VHDL ist KEINE Programmiersprache!

von Penibeli (Gast)


Lesenswert?

Kommt auf die Definition von Programmiersprache an.
Wenn man ganz pingelig sein will lädt man im FPGA ja wirklich ein 
Programm in einen Speicher. ;-)

von Jens (Gast)


Angehängte Dateien:

Lesenswert?

@Zack:

Tips zu Deinem VHDL-Kode gebe ich lieber nicht, schließlich habe
ich vor einigen Wochen auch erst angefangen mich mit VHDL zu
beschäftigen. Mein erstes Projekt ist ähnlich, ein Sekundenzähler
für die 7-Segment-Anzeige auf dem Spartan3-Starterkit. Siehe Anhang.
Was mir allerdings aufgefallen ist, Du beschreibst Dein Design in
einer einzigen Datei. Ich habe während der ersten Schritte immer
versucht ganz kleine Einheiten zu beschreiben und diese dann Stück
für Stück zusammenzusetzen. So kann man relativ leicht im RTL-Viewer
kontrollieren was die Synthese aus dem Quellkode erzeugt hat. Gerade
bei so einfachen Schaltungen habe ich eine gute Vorstellung wie die
Implementierung aussehen kann. Da probiere ich dann auch mal
verschiedene Beschreibungen aus bis das Ergebniss meinen Vorstellungen
entspricht.

Jens

von wasi (Gast)


Lesenswert?

Hallo Zack B,

hier ist noch ein anderer Algorithmus für die binär zu BCD
Umwandlung (dreierkorrektur) :

1. Man definiere zwei Register,das eine wird als Binärzahl
ohne Vorzeichen interpretiert das andere enthält die BCD
Tetraden.Z.B für die Umwandlung einer 8 bit Binärzahl wäre
das Binärregister std_logic_vector(7 downto 0) und das BCD
Register std_logic_vector(11 downto 0),also drei Tetraden.

2. Die Register werden so verschaltet,dass man das MSB des
Binärregisters in das LSB des BCD Registers hineinschieben
kann.

3. Ein Schleifenzähler Zählt von 8 (Anzahl der Bits des
   Binärregisters) bis auf 0 runter,dann ist die Umwandlung fertig.

4. Zustand INIT:
   Binärzahl in das Binärregister übernehmen,BCD Regster
   löschen,Schleifenzähler auf 8 setzen.
   GOTO CONVERT

5. Zustand CONVERT:
   Wenn eine der BCD Tetraden > 4 ist,dann GOTO ADD,
   sonst GOTO SHIFT.

6. Zustand ADD:
   Addiere zu den Tetraden die > 4 sind 3 dazu,die anderen
   behalten ihren alten Inhalt.
   GOTO SHIFT.

7. Zustand SHIFT:
   Wenn der Schleifenzähler = 0 ist, dann GOTO FERTIG,
   sonst:
     7.1 Schiebe das BCD und das Binärregister um eine Stelle
     nach links,wobei das MSB des Binärregisters in das
     LSB des BCD Registers hineingeschoben wird.Das LSB
     des Binärregisters wird mit '0' gefüllt.
     7.2 Dekrementiere den Schleifenzähler.
     7.3 GOTO CONVERT.

8. Zustand FERTIG:
   Das BCD Register enthält nun die BCD Kodierte Binärzahl.

(Das habe ich jetzt bischen aus der Erinnerung heraus geschrieben,
bitte um Verzeihung wenn im Algorithmus ein Fehler drin ist.)

Literatur:
Jorke,Lampe,Wengel
"Arithmetische Algorithmen der Mikrorechentechnik"
VEB Verlag Berlin.

Veruche doch einen Datenpfad für die Rechnerei zu implementieren und
eine Zustandsmaschine welche den Datenpfad steuert.Der Datenpfad
erzeugt wiederum Steuersignale welche von der Zustandsmaschine für
die Ermittlung des Folgezustandes verwendet werden.

Wenn deine Implementierung Synthetisiert,dann wird daraus mit sicherheit
eine Menge Hardware draus werden!

Viel Erfolg!

von Stefan W. (wswbln)


Lesenswert?

Penibeli wrote:
> ...
> Wenn man ganz pingelig sein will lädt man im FPGA ja wirklich ein
> Programm in einen Speicher. ;-)

...und im ASIC??

[ ] Du hast verstanden


@wasi: AU WEIA!

Was ist an dem "Design" eigentlich so schwierig? 4 Instanzierungen eines 
dekadischen Zählers und 4 Instanzierungen eines BCD-to-7Seg-Dekoders 
plus ein bisschen Logik für die Einstellung mit den Tasten..... Oder 
sehe ich das völlig falsch??

von Johannes T. (johnsn)


Lesenswert?

Penibeli wrote:
> Kommt auf die Definition von Programmiersprache an.
> Wenn man ganz pingelig sein will lädt man im FPGA ja wirklich ein
> Programm in einen Speicher. ;-)

Nein. Du lädst das FPGA mit einer Konfiguration!
Du kompilierst nicht, du macht in erster Linie eine Synthese, danach 
folgt Place & Route! Das hat absolut nichts mit Maschinenbefehle, die 
von einer CPU abgearbeitet werden zu tun.

Aber passiert auch mir oft, dass ich "VHDL programmieren" sage.

von Zack B. (zack)


Lesenswert?

Vielen Dank für Eure Antworten, ich werde mein Programm dann noch mal 
überarbeiten. Dazu bräuchte ich allerdings noch ein bischen Hilfe von 
Euch, hoffe ihr habt ein paar Minuten!


@Falk & andere Helfer
- Zu numberLocal: ich habe dass gemacht, da ich gehört habe, dass 
Signale den übergebenen Wert erst im nächsten "Durchlauf" annehmen. 
Würde es dann nicht Probleme mit der nächsten if Abfrage (if 
numberLocal>9999 ) geben?
- Casesensitive: ich werde nie versuchen 2 verschiedene Variblen mit 
local und Local zu instanzieren, oder was meinst du? Ich mache das nur, 
weil es für mich übersichtlicher ist.
- overflow: ich habe darüber keine genaue Definition gefunden. Ist es 
so, dass beim Schritt von 9999 auf zB 10099 der Wert auf 99 gesetzt 
wird? Was passiert beim underflow, falls ich sowas irgendmal benutzen 
sollte. Ist das bei allen Datentypen gleich?
- BCD: Ich hab da viel Zeit gelassen, am Anfang wollte ich halt einfach 
durch 1000 teilen, dann durch 100 und so weiter. Schnell musste ich dann 
aber die Andersartigkeit eines FPGAs erkennen ;)
Ich weiss wirklich nicht, wie ich das jetzt verbessern sollte. Irgendwie 
muss ich ja an die Ziffern kommen. Hat jemand noch Ideen?
edit: werde auch schon mal den Vorschlag von wasi näher untersuchen.
- BTN0old: An dem process hab ich auch laenger gesessen und 
verschiedenste Varianten probiert. Zwischenzeitlich wollte ich für alle 
Buttons per if eine 'last Abfrage machen, aber das darf man wohl nicht. 
Auch hier sehe ich momentan keine andere Möglickeit und würde mich über 
Tipps freuen! Insbesondere würde ich auch gerne wissen, wieso ich mir 
dadurch ins Knie schiessen würde, damit ich sowas nicht mehr mache.


@stefan
Zitat:
> Hauptfunktion soll sein, eine Zahl von 0 bis 9999 anzuzeigen.
(Die zB über eine SPI Verbingung gelsen wird)

daher ist es denke ich nicht so einfach mit ein paar Bauteilen zu lösen.



Vielen Dank nochmals!

von Falk B. (falk)


Lesenswert?

@ Zack B. (zack)

>Würde es dann nicht Probleme mit der nächsten if Abfrage (if
>numberLocal>9999 ) geben?

Nein. Es werden alle Anweisugen der Reihe nach ausgewertet (vom 
Compiler), die letzte Anweisung hat Priorität gegenüber den 
vorhergehenden Anweisungen. In Hardware erfolgt die Auswertung logischer 
wise parallel, mit eben dieser Priorität.

>- Casesensitive: ich werde nie versuchen 2 verschiedene Variblen mit
>local und Local zu instanzieren,

Geht auch gar nicht in VHDL :-)

>- overflow: ich habe darüber keine genaue Definition gefunden. Ist es
>so, dass beim Schritt von 9999 auf zB 10099 der Wert auf 99 gesetzt

Nein, die Zähler sind ja alle binär, da gibt es nur an binären grenzen 
einen Overflow. Ich sprach auch von ctr.

>wird? Was passiert beim underflow, falls ich sowas irgendmal benutzen

Das gleich wie beim Overflow, man landet "oben" im Zahlenbereich.

>sollte. Ist das bei allen Datentypen gleich?


AFAIK ja.

>Ich weiss wirklich nicht, wie ich das jetzt verbessern sollte. Irgendwie
>muss ich ja an die Ziffern kommen. Hat jemand noch Ideen?

Gleich in BCD zählen/rechnen.

>Buttons per if eine 'last Abfrage machen, aber das darf man wohl nicht.

Ja. Siehe 
http://www.mikrocontroller.net/articles/VHDL_Schnipsel_Flankenerkennung

MFG
Falk

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.