Um ein bisschen tiefer in die VHDL/CPLD Materie einzutauchen habe ich mal eine 7-Segment Digitaluhr entworfen. Der Code besteht aus einem Frequenzteiler, 6 Binärzählern und einem 7-Segment-Encoder. Die Segmente werden gemultiplext. Es funktioniert auch alles soweit und passt gerade so in mein XC9572XL-10-VQ44 (71/72 Macrocells used). Wäre nett, wenn mal jemand über den Code schauen könnte ob da noch Optimierungspotential besteht. Habe ich da unbeabsichtigt irgendwo unnötige Latches einfegügt? Nach meiner Rechnung werden Makrozellen verbraucht für Teiler 8MHz->2kHz: 12 Teiler 2kHz->1Hz: 11 6 Binärzähler x 4 Bit: 24 Index-Counter 0..5: 3 Summe: 50 Der Rest ist ja eigentlich nur Kombinatorik. Ist es normal, dass da nochmal 21 Zellen draufgehen? Andreas
1 | Start time: 07:34:50 on Jul 14,2015 |
2 | vcom uhr.vhd |
3 | Model Technology ModelSim SE-64 vcom 10.3d Compiler 2014.10 Oct 7 2014 |
4 | -- Loading package STANDARD |
5 | -- Loading package TEXTIO |
6 | -- Loading package std_logic_1164 |
7 | -- Loading package NUMERIC_STD |
8 | -- Loading package std_logic_arith |
9 | -- Loading package STD_LOGIC_UNSIGNED |
10 | -- Compiling entity main |
11 | -- Compiling architecture Behavioral of main |
12 | End time: 07:34:50 on Jul 14,2015, Elapsed time: 0:00:00 |
13 | Errors: 0, Warnings: 0 |
std_logic_arith und std_logic_unsigned müssen raus. Die bringen auf Dauer nur Unglück. Siehe auch: Beitrag "IEEE.STD_LOGIC_ARITH.ALL obsolete"
1 | Mapping a total of 65 equations into 4 function blocks...........................................................................................................................................ERROR:Cpld:892 - Cannot place signal index<0>. Consider reducing the collapsing |
2 | input limit or the product term limit to prevent the fitter from creating |
3 | high input and/or high product term functions. |
4 | ............ |
5 | ERROR:Cpld:868 - Cannot fit the design into any of the specified devices with |
6 | the selected implementation options. |
Was hast Du für Einstellungen zum Fitten verwendet? Die Standardeinstellungen (ISE 14.6) scheinen nicht zu klappen.
1 | Found 11-bit down counter for signal <cntHz>. |
2 | Found 12-bit down counter for signal <cntkHz>. |
Mit einem langsameren Takt, kannst Du beim Teiler sparen. Dafür wurden mal die 32.768 kHz Quarze erfunden. Viel sparen läßt sich m.E. nicht mehr, es sei denn Du verzichtest auf den Reset. Vielleicht hilft es noch, wenn die Digit-Timer nicht als Prioritätenkette formuliert werden. Im FPGA würde ich die Abfrage des Zählerstandes definitif lesbarar schreiben:
1 | ...
|
2 | if digits(2) = 9 then |
3 | digits(2) <= x"0"; |
4 | ...
|
Aber da kommt es auch nicht auf die letzte Makrozelle an, sondern auf Wartbarkeit/Lesbarkeit. Duke
Danke für deine Rückmeldung. Ich habe den Compiler schon auf Density optimieren lassen. Ich weiß, dass ich an den Teilerstufen noch was sparen kann. Habe im Moment eben einen 8MHz Generator angeschlossen. Das ist auch kein "ernsthaftes" Projekt; es geht mir in erster Linie um den Lerneffekt und ich wollte mal sehen wie weit man so ein CPLD ausreizen kann. Und das Ergebnis finde ich echt überzeugend. Wenn ich daran denke, welches TTL-Grab meine in den 80-er Jahren gebaute Uhr war :-)
Andreas R. schrieb: > Der Rest ist ja eigentlich nur Kombinatorik. Ist es normal, dass da > nochmal 21 Zellen draufgehen? Auch die Logik und damit die Ausgangsmultiplexer brauchen Produktterme...
Lothar, noch mal eine Grundlagenfrage: Als C-Programmierer würde ich sowas
1 | with index select |
2 | anodBits <= "000001" when 0, |
3 | "000010" when 1, |
4 | "000100" when 2, |
5 | "001000" when 3, |
6 | "010000" when 4, |
7 | "100000" when 5; |
als Schieben einer Konstante schreiben also
1 | anodBits = 1UL << index; |
Gibt es so etwas auch in VHDL?
Andreas R. schrieb: > Gibt es so etwas auch in VHDL? Ja:
1 | process( index) |
2 | begin
|
3 | anodBits <= ( others => '0'); |
4 | anodBits( index) <= '1'; |
5 | end process; |
Duke
Ok danke, ist ja eigentlich ganz einfach, aber als C-Programmierer geht man manchmal von der falschen Seite an die Sache heran.
Eine Makrozelle spart man noch, wenn man Reset richtig als asynchronen Reset hinschreibt:
1 | counters : process(CLK, RST) |
2 | begin
|
3 | if RST = '0' then |
4 | digits(0) <= x"0"; |
5 | digits(1) <= x"0"; |
6 | digits(2) <= x"0"; |
7 | digits(3) <= x"0"; |
8 | digits(4) <= x"2"; |
9 | digits(5) <= x"1"; |
10 | elsif rising_edge(CLK) then |
11 | ...
|
Da wird Reset auf GSR gemappt (was sowieso im Chip vorhanden ist). Duke
Andreas R. schrieb: > 6 Binärzähler x 4 Bit: 24 Da sollten sich 4 FFs sparen lassen (Zähler 0..5 bzw. 0..2). Andreas R. schrieb: > Index-Counter 0..5: 3 Als SRG aus 6FFs spart den zusätzlichen Decoder (6 Logik-Gatter). Kombinatorik ohne oder mit FF ist egal, kostet immer eine Macrozelle.
:
Bearbeitet durch User
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.