Forum: FPGA, VHDL & Co. Ressourcenverbrauch bei Vergleich


von Arne S. (Gast)


Lesenswert?

Moin zusammen,

habe ein Implementierungsproblem in VHDL.

Device: Xilinx XC95144XL
Entw.umgebung: ISE 14.7

Ich möchte feststellen, ob die am CPLD anliegende Adresse bzw. der obere 
Teil davon mit einem zuvor gespeicherten Teil übereintimmt. Dadurch will 
ich erkennen, ob die CPU auf die gerade aktivierte Page im RAM zugreift 
oder ich diese schließen und eine andere Page öffnen muss.
1
entity RAM is
2
    port(
3
        -- CPUST side
4
        CLK32                   : in std_logic;
5
        CPU_RESET               : in std_logic;
6
        CPU_ADDR                : in std_logic_vector(23 downto 1);
7
        (..)
8
    );
9
end entity;
10
11
architecture Behaviour of RAM is
12
    (..)
13
    signal RAM_PAGE_ACTIVE      : std_logic_vector(23 downto 10);
14
    (..)
15
    process(CLK32) begin
16
        if rising_edge(CLK32) then
17
            case FSMState is
18
                (..)
19
                when PAGE_ACTIVATE =>
20
                    RAM_PAGE_ACTIVE <= CPU_ADDR(23 downto 10);
21
                    (..)
22
                when BANK_IS_ACTIVE =>
23
                    if (CPU_ADDR(23 downto 10) = RAM_PAGE_ACTIVE) then      -- um diesen Vergleich geht es
24
                        (..)
25
                end if;
26
            end case;
27
        end if;
28
    end process;
29
end architecture;
In einem Process wird meine FSM an jeder steigenden CLK32 Flanke 
aufgerufen. Im Zustand PAGE_ACTIVATE merke ich mir die zu öffnende Page, 
damit ich im Zustand BANK_IS_ACTIVE diese mit der gerade an den CPLD 
Pins anliegenden Adresse vergleichen kann (d.h. die Bits 23..10).
Nun ist mir aufgefallen, daß dieser Vergleich extrem viele ProductTerms 
wegfrisst: 50 je zu vergleichendem Bit! Und im 95144 habe ich "nur" 720!
An anderer Stelle vergleiche ich die CPU_ADDR mit konstanten Werten, um 
zu sehen, ob auf mein RAM zugegriffen werden soll. Also ein 
address-range-check!
1
    if (CPU_ADDR(23 downto 20) = "1100") then   -- Zugriff auf $Cxxxxx
2
        (..)
3
    end if;
Das geht sehr billig, aber der Kosten für einen Vergleich mit einem sich 
zur Laufzeit änderbarem Wert gehen durch die Decke.
Bin mir sicher, daß ich etwas falsch mache. Aber was?

Danke.

von Duke Scarring (Gast)


Lesenswert?

Arne S. schrieb:
> RAM_PAGE_ACTIVE <= CPU_ADDR(23 downto 10);
Versuch mal diese Zeile aus dem Prozess rauszunehmen und das Signal 
direkt kombinatorisch zu erzeugen. Beim CPLD muß man eher in 74xx 
'denken', als in VHDL.

Duke

von Knoten im Taschentuch (Gast)


Lesenswert?

Schreibs in Subtracter um und teste das Ergebniss auf 0

von Arne S. (Gast)


Lesenswert?

Duke Scarring schrieb:
> Arne S. schrieb:
>> RAM_PAGE_ACTIVE <= CPU_ADDR(23 downto 10);
> Versuch mal diese Zeile aus dem Prozess rauszunehmen und das Signal
> direkt kombinatorisch zu erzeugen. Beim CPLD muß man eher in 74xx
> 'denken', als in VHDL.
Hat letztendlich eher nichts gebracht. Der Verbrauch an ProductTerms ist 
von 518 auf 435 runtergegangen. "FBInputs used" hingegen von 275 auf 306 
gestiegen. Beide Designs kann ich nur mit 28MHz takten - viel zu wenig. 
Vor dieser Änderung auf Pageadressenvergleich waren es 87MHz.

Knoten im Taschentuch schrieb:
> Schreibs in Subtracter um und teste das Ergebniss auf 0
Das war sogar vollkommen kontraproduktiv, da der Fitter terminierte:

"encountered a memory conflict.  Current memory usage is 2090548 kb. 
You can try increasing your system's physical or virtual memory.  If you 
are using a Win32 system, you can increase your application memory from 
2GB to 3GB using the /3G switch in your boot.ini file. For more 
information on this, please refer to Xilinx Answer Record #14932. For 
technical support on this issue, please visit 
http://www.xilinx.com/support.
A Xilinx application has run out of memory, the current memory usage is: 
2090676 kb

Process "Fit" failed"
2GB haben nicht gereicht. Ich glaube da ist schon was bei Xilinx schief 
gelaufen.

von Knoten im Taschentuch (Gast)


Angehängte Dateien:

Lesenswert?

Arne S. schrieb:
> Knoten im Taschentuch schrieb:
>> Schreibs in Subtracter um und teste das Ergebniss auf 0
> Das war sogar vollkommen kontraproduktiv, da der Fitter terminierte:

Hab überlesen das du nur ein CPLD hast. Mglw. ist da die FSM ein 
problem, da ein CPLD keine interne FF hat, nur eins pro pin.

Reset-netzwerke gibt es auch nicht viele, also reset einsparen wo 
möglich. Nicht das da mit den macrocellen was nachgebastelt wird.

von Knoten im Taschentuch (Gast)


Lesenswert?

Knoten im Taschentuch schrieb:
> problem, da ein CPLD keine interne FF hat, nur eins pro pin.

Missverständlich, klar hat ein CPLD auch intern FF (dort register) 
genannt, aber die sind eigentlich als Output-Pad FF designed und liegen 
bei den Gehäusepins. Bei deinem CPLD haste 144 davon. wenn du mit 
One-Hot encoding arbeitest kannste vielleicht ein paar macrozellen 
schleifen sparen.

bei den cpldfit Optionen sollte man auch mal reinschauen, vielleicht 
fehlt ne Optimierung: 
https://www.xilinx.com/htmldocs/xilinx11/devref.pdf S. 247ff

Auch dem XST kann man hinsichtlich FSM-Extraction/-Synthese ein paar 
Tipps mitgeben.

von Achim S. (Gast)


Lesenswert?

Arne S. schrieb:
> Bin mir sicher, daß ich etwas falsch mache. Aber was?

Du machst nichts falsch, deine Beobachtung ist für CPLDs normal. Die 
müssen die Logik auf eine UND-ODER Matrix abbilden. Und damit ist der 
Vergleich mit einer fest vorgegebenen Adresse viel einfacher 
implementierbar als der Vergleich von zwei (zur Laufzeit variablen) 
Registerwerten.

Um z.B. zu prüfen, ob Adresse A den festen Wert 1010 hat, reicht ein 
p-Term

y = A3 and !A2 and A1 and !A0

Aber um zu vergleichen, ob zwei Register identisch ist, musst du alle 
Bitkombinationen per UND-ODER abfragen. Für ein einzelnes Adressbit 
sieht die Logik dann folgendermaßen aus:

y = (A0 and B0) or (!A0 and !B0)

Wenn die Adressbreite größer wird, explodiert der Aufwand für den 
Vergleich, weil jeweils alle möglichen Bitkombinationen abgedeckt werden 
müssen. Also für eine Adressbreite von zwei Bits schon:

y = (A0 and B0 and A1 and B1) or (!A0 and !B0 and A1 and B1) or (A0 and 
B0 and !A1 and !B1) or (!A0 and !B0 and !A1 and !B1)

Die Und-Oder Matrix in der CPLD-Logik ist für solche Vergleich einfach 
ungünstig. Mit der Look-Up Table in einem kleinen FPGA hättest du das 
Problem nicht.

von Arne S. (Gast)


Lesenswert?

Knoten im Taschentuch schrieb:
> bei den cpldfit Optionen sollte man auch mal reinschauen, vielleicht
> fehlt ne Optimierung:
> https://www.xilinx.com/htmldocs/xilinx11/devref.pdf S. 247ff
Da schaue ich mal rein. Danke!

Achim S. schrieb:
> Mit der Look-Up Table in einem kleinen FPGA hättest du das
> Problem nicht.
Schon möglich, aber dafür dann andere Probleme. Z.B. keine 5V toleranten 
Pins. Oder kennst Du da eines in nicht-BGA-Gehäuse?

von Knoten im Taschentuch (Gast)


Lesenswert?

Arne S. schrieb:
>> Mit der Look-Up Table in einem kleinen FPGA hättest du das
>> Problem nicht.
> Schon möglich, aber dafür dann andere Probleme. Z.B. keine 5V toleranten
> Pins. Oder kennst Du da eines in nicht-BGA-Gehäuse?

Kennen schon, das sind aber Methusalixe wie Spartan XL.

https://lhcb-online.web.cern.ch/ecs/ccpc/docs/XCS05xl%20datasheet.pdf


Aber schau mal OHO vorbei, die haben da welche samt Levelshifter auf DIL 
getrimmt:

http://www.oho-elektronik.de/index.php?c=1&s=gop_xc3s200

von Arne S. (Gast)


Lesenswert?

Dann ist mein Plan B, daß ich den 14-Bit Vektor (RAM_PAGE_ACTIVE ) über 
zwei 74F573 latche und zum Vergleich dann die Latchausgänge und die 
CPU_ADDR zwei 74F521 8-Bit Komparatoren vorwerfe und die beiden /P=Q 
Ausgänge dann in das CPLD führe.

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.