Makrozellenverbrauch reduzieren

#4197297
Lesenswert?

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
Angehängte Dateien:
Gast #4197616
Lesenswert?

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
#4197629
Lesenswert?

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 :-)
#4197640
Lesenswert?

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?
Gast #4197676
Lesenswert?

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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren