Forum: FPGA, VHDL & Co. Benötigt ein MUX Macrozellen im CPLD?


von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Bevor ich jezt unötig suche wo mein Fehler ist frage ich mal hier nach:

Ich habe zwei Register(ramAddr, temp_trigger) die ich abhängig von einem 
Eingangssignal(readRam) auf einen Ausgang(ram_addr) schalten möchte.
1
process(ramAddr, readRam, temp_trigger)
2
begin
3
 case readRam is
4
  when '0' =>
5
   ram_addr <= ramAddr;
6
  when others =>
7
   ram_addr <= temp_trigger(addresswidth-1 downto 0);
8
 end case;
9
end process;

Jezt ist es aber leider so das die Synthese nicht (wie ich erwartet 
hätte) das ganze in Logik abbildet sondern ein drittes Register einbaut 
mit dem ergebnis dass ich statt 2*addresswidth, 3*addresswidth 
Makrozellen benötige.

Braucht man für einen Multiplexer generell Makrozellen in nem CPLD oder 
hab ich einfach an anderer Stelle etwas vergurkt das die Synthese das so 
machen muß?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> Braucht man für einen Multiplexer generell Makrozellen in nem CPLD
Jede logische Funktion braucht Makrozellen...
Eine Makrozelle besteht aus der Logik-Matrix und einem angehängten FF. 
Ob du das FF verwendest oder nicht: die Makrozelle ist weg, auch wenn 
"nur" Kombinatorik aufgebaut wird.

> sondern ein drittes Register einbaut
Dass das jetzt registriert werden soll, ist allerdings eigenartig.

BTW:
Du könntest das auch einfach concurrent in einer Zeile beschreiben:
1
   ram_addr <= ramAddr when readRam='0' else ram_addr <= temp_trigger(addresswidth-1 downto 0);

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Lothar Miller schrieb:
> Du könntest das auch einfach concurrent in einer Zeile beschreiben:
>
1
>    ram_addr <= ramAddr when readRam='0' else ram_addr <=
2
> temp_trigger(addresswidth-1 downto 0);
3
>
Ja so hatte ich es am Anfang mit dem selben Ergebnis, hatte gehoft das 
die Synthese vieleicht so meine Absicht besser erkenne kann...

> Jede logische Funktion braucht Makrozellen...
Ja okay aber...
> Dass das jetzt registriert werden soll, ist allerdings eigenartig
Ich war halt davon ausgegangen das nur das FF für ramAddr und 
temp_trigger einfach nur entsprechend verdrahtet, Logik Recourcen sind 
nämlich noch genug frei nur die FF/Register/Makrozelle Recourcen sind 
dem Fitter dan zu wenig weil er halt nochmal die gleiche Anzahl 
Speicherlelemente vor den Ausgang packt.

Deshalb habe ich mich gefragt ob in nem CPLD ein MUX vieleicht generell 
Speicherelemente benötigt.

von Läubi .. (laeubi) Benutzerseite


Angehängte Dateien:

Lesenswert?

Lothar Miller schrieb:
> Dass das jetzt registriert werden soll, ist allerdings eigenartig
Hab mich verguckt, er macht wohl doch kein Register draus, trozdem 
benötigt er eine volle Makrozelle pro Bit, ohne die Zeile:
1
ram_addr <= ramAddr when readRam='0' else temp_trigger(addresswidth-1 downto 0);
benötige ich 66 Makrozellen,
mit der Zeile meckert der Fitter: 'Insufficient number of macrocells. 
The design needs at least 81' also 15 zuwenig, das ist genau die Zahl 
von addresswidth.

Habe mal ein Bild vom RTL View angehängt, vieleicht sieht man dann 
besser was ich vor habe.

Der Ausgang 'ram_addr' geht an die Adressleitung eines SRAMs und soll 
entweder vom Adresszähler bestimmt werden oder vom Inhalt von Triger 
Data und Trigger Mask (bei 2) (Beide zusammen sind temp_trigger).

Unten ist das SPI Modul welches das Register temp_trigger beschreibt.

Wenn ich das ganze taktgesteuert mache, zeigt er mir das auch als MUX 
an und fügt auch ein Register ein... Ich dachte nur das die Ausgänge 
schon eigensctändige Register hätten... ich bin auf jedenfall etwas 
verwirrt.
1
process
2
  begin
3
    wait until rising_edge(clk);
4
    case readRam is
5
      when '0' =>
6
        ram_addr <= ramAddr;
7
      when others =>
8
        ram_addr <= temp_trigger(addresswidth-1 downto 0);
9
    end case;
10
  end process;

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> ram_addr
hat 16 Bit.
Und wenn das gemuxt und ausgegeben werden soll, dann braucht jedes 
einzelne Bit eine Makrozelle.

Allein eine Funktion wie
1
c <= a(23) and b(1);
 braucht eine Makrozelle. Genauso braucht eine Funktion wie
1
c <= '1' when a(23 downto 4) = b(21 downto 2) else '0';
 eine Makrozelle. CPLDs sind sehr schön für Adressdecoder, aber extrem 
uneffizient z.B. für Zähler.

von Michael (Gast)


Lesenswert?

Zumindest bei Xilinx CPLDs (XC95xx) habe ich folgende Erfahrungen 
gemacht:

Jede I/O Zelle ist mit einer Makrozelle gekoppelt. Ist in die zu einem 
I/O Signal gehörige Makrozelle keine Logik & FF gemapped, ist sie 
trotzdem nicht mehr nutzbar.

Die CPLDs verfügen nur über gegrenzte Routingmöglichkeiten. D.h. wenn es 
viele logische Verbindungen zwischen den FF-Ausgängen und den 
LUT-Eingängen gibt, so kann dies zu einem Engpass bei den Fast Routing 
Netzwerken kommen. Damit können einige Makrozellen nicht genutzt werden.

Generell auch bei FPGAs können bei 4-LUT Tabellen keine 5 oder mehr 
Signale in einer Zelle abgebildet werden. Die Logik wird auf zwei oder 
mehr Zellen verteilt. Dadurch ensteht wiederum höherer Routingaufwand 
und möglicherweise noch weniger Zellen stehen zur Verfügung.

Schau mal hier:
http://www.xilinx.com/support/documentation/data_sheets/ds054.pdf

Ab Seite 3 werden die einzelnen Blöcke erklärt.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Lothar Miller schrieb:
>Allein eine Funktion wie
Gerade mal ausprobiert, du hast tatsächlich recht.
Gibt es da einen Grund für? Ich meine hier wird ja nichts gespeichert, 
daher hatte ich gedacht, dass einfach die Logik der Zellen a(23) und 
b(1) benuzt wird um c zu berechnen.

> CPLDs sind sehr schön für Adressdecoder,
> aber extrem uneffizient z.B. für Zähler.
Gut das jedes Zählbit zwansläufig eine Speicherzelle belegt hab ich ja 
schon einberechnet.

Gibt es den irgeneine Möglichkeit/Trick wie ich das gewünschte Umsetzen 
könnte ohne nen größeren CPLD?

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Michael schrieb:
> http://www.xilinx.com/support/documentation/data_sheets/ds054.pdf
>
> Ab Seite 3 werden die einzelnen Blöcke erklärt.
Hatte mir das Dateblatt natürlich angeschaut nur wohl zu oberflächlich 
dort steht ja explizit drin zu Figure 1:
1
Note: Function block outputs (indicated by the bold lines) drive the I/O blocks directly.
Also meine erste falsch Annahme war wohl das die I/O eigene Puffer 
haben, also jeder Ausgang braucht mind. 1 Macrozelle.
1
Each XC9500XL macrocell may be individually configured
2
for a combinatorial or registered function
Zweite Falschannahme war wohl das man durch verwenden von Asyncroner 
Logik nur "Logikrecourcen" verbraucht.

Naja also muß ich mein Konzept nochmal überdenken irgenwie krieg ich das 
schon in die 77 Macrozellen reingequetscht :D

von Iulius (Gast)


Lesenswert?

wie wärs wenn du den temp_trigger raus nimmst und den ausgang direkt mit 
der davor stehenden logik verbindest ?

kenne natürlich dein Design nicht und weiß daher nicht ob der 
temp_trigger um nen takt verzögert ist o.ä...

Falls ja wird das wohl nichts.

von Michael (Gast)


Lesenswert?

Kannst Du nicht mit einem externen 8Bit Latch für die unterenen / oberen 
8Bit Adressen arbeiten? Würdest Dir 7 Ausgangsleitungen sparen :)

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Naja Sinn des CPLD ist ja möglichst externe HW zu sparen. Ich habe das 
jezt so gelöst, das das Counter Modul einen weiteren Eingang bekommt mit 
dem man ein Weiterzählen trotz Stop bedingung erreicht, und den 
Datenport an das Schieberegister gelegt.
Auf diese Weise kann man zwar nicht wahlweise lesen, das ist hier aber 
auch nicht nötig, dadurch habe ich zudem nochmal 4 Makrozellen gespart 
die jezt für andere 'Überraschungen' herhalten können, und es wird kein 
Lesesignal mehr benötigt (das erzwungene hochzählen wird jezt durch das 
einsyncronisierte CS Signal realisiert).

Im Nachhinnein ist das wohl auch die bessere Lösung, naja hinterher ist 
man immer schlauer und dümmer bin ich durch den Versuch auch nicht 
geworden :)
Trozdem danke für die Mithilfe.

von Michael (Gast)


Lesenswert?

Naja, letzten Endes ist die Summe allen Übels konstant.

Entweder spendierst Du ein größeres CPLD (zumindest mit mehr Logikzellen 
- ist natürlich teurer) oder fügst billig-chips 74hc... für einzelne 
dedizierte Aufgaben hinzu. Die logischen Verknüpfungen zur Ansteuerung 
kannst Du ja weiter im CPLD lassen :).

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Michael schrieb:
> Naja, letzten Endes ist die Summe allen Übels konstant.

Ja das stimmt wohl ich hab es jezt mit etwas Nachdenken gelöst, die wohl 
beste Lösung :)
Wenn alles so läuft wie geplant werd ich das ganze hier mal vorstellen.
(Oder nochmal nachfragen falls es Probleme gibt :D)

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Was ich mich jezt allerdings frage:

Wie sieht das mit Taktteilern aus? Lieber extern machen oder mal intern 
probieren?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> Wie sieht das mit Taktteilern aus? Lieber extern machen oder mal intern
> probieren?
Besser intern, aber Platzbedarf pro Takthalbierung: 1 Makrozelle.

Wie gesagt: CPLDs kommen aus der PAL/GAL-Ecke, und die wurden für 
Logikmonster erfunden. Deshalb haben CPLDs nur wenige Register. Zum 
Zählen, Speichern usw. sind sie deshalb eigentlich schlecht geeignet. 
Für jeden Zählschritt verlierst du die ganze mächtige Kombniatorik der 
Makrozelle...

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Okay, habe noch 4 Makrozellen freigehabt und mal folgendes gebastelt:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.numeric_std.ALL;
4
5
entity clkdiv_module is
6
    Port ( clk : in  STD_LOGIC;
7
           div : in  STD_LOGIC_VECTOR (1 downto 0);
8
           ena : out  STD_LOGIC);
9
end clkdiv_module;
10
11
architecture Behavioral of clkdiv_module is
12
signal stlv_cnt : UNSIGNED(2 downto 0); 
13
begin
14
    divider: process
15
    begin
16
        wait until rising_edge(clk);
17
        stlv_cnt <= stlv_cnt + 1;
18
        case div is
19
            when "00" => 
20
                ena <= '1';
21
            when "01" =>
22
                ena <= stlv_cnt(0);
23
            when "10" =>
24
                ena <= stlv_cnt(0) AND NOT stlv_cnt(1);
25
            when others => 
26
                ena <= stlv_cnt(0) AND stlv_cnt(1) AND stlv_cnt(2);
27
        end case;
28
    end process;
29
end Behavioral;
Solange 'stlv_cnt' 2 Bit breit ist klappt das auch noch und ich habe 
noch 2 Macrozelllen frei, bei 3 Bit kann der Fitter es nicht mehr 
reinpacken, ich lass grad mall den Exhaustive Fit Mode durchlaufen, mal 
gucken obs nicht doch noch passt :)

Hätte aber noch ne Frage :
div soll von außen durch einen AVR vorgegeben werden, ist aber die 
meisste Zeit statisch (also wird nur ganz am Anfang mal gesezt). Müßte 
man das trozdem einsyncronisieren?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> Müßte man das trozdem einsyncronisieren?
Nein.
Du kannst ja ohne weiteres irgendwelche Fehler, die beim Umschalten 
passieren, einfach ignorieren.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Super, das einzige 'Problem' was mich derzeit noch quält ist, das ich 
zwar noch 2 Makrozellen frei habe, sobald ich aber irgenwo eine weitere 
verwenden möchte (für einen Zähler oder Schieberegister) schlägt das 
fitten fehl! (auch der exhaustive Fit).
Gibt es sowas wie nen "Floorplan View" wo man gff sehen kann wo es hakt?

von Falk B. (falk)


Lesenswert?

Chip viewer.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Falk Brunner schrieb:
> Chip viewer
Ab welcher ISE Version ist das den Dabei ich kann das bei mir nicht 
finden, weder in den ISE Menüs noch im Programmordner.

von Falk B. (falk)


Lesenswert?

@  Läubi .. (laeubi) Benutzerseite

>> Chip viewer
>Ab welcher ISE Version ist das den Dabei ich kann das bei mir nicht
>finden, weder in den ISE Menüs noch im Programmordner.

Bei meiner Version 6.3 ist der im Menu unter FIT -> View fitted 
design(chip viewer)

MFG
Falk

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Bei ISE 9.1 gibt es unter Fit nur 'View Fitter Report'... vieleicht 
liegts am WebPack oder muß man das extra installieren?
Laut Xilinx Website sollte es aber angeblich in ISE dabei sein... 
komisch.

von Klaus Falser (Gast)


Lesenswert?

> Gibt es sowas wie nen "Floorplan View" wo man gff sehen kann wo es hakt?

Meiner Meinung nach ist das beste Werkzeug beim CPLD (Xilinx) immer noch 
der Fitting Report, und zwar der Teil mit den Gleichungen (Equations).
Die Gleichungen, also die Signale, bei denen zu viele Produktterme 
verwendet werden, sind die kritischen. Manchmal geht es nicht anders, 
aber manchmal kann man sich auch überlegen ob man die Funktion des 
Signals nicht ein  bischen ändern kann (größer oder kleiner Operationen 
sind eine Katastrophe), sodass die Gleichungen nicht so kompliziert 
werden.
Im allgemeinen kann man sagen, dass man bei Ein-/Ausgangssignalen (falls 
möglich) immer eine Makrozelle dazwischen freilassen sollte, und zwar 
deshalb weil bei komplizierteren Gleichungen der Fitter von der 
Nachbarzelle Produktterme stehlen muss. Diese Nachbarzelle steht dann 
nicht mehr für ein Signal zur Verfügung.
Besonders bei einem Mux zwischen mehr als 5 Eingangssignalen werden mehr 
Produktterme benötigt als pro Makrozelle vorhanden.
Eine Einschränkung von Xilinx CPLD (vielleicht auch Altera, das weiss 
ich nicht), die zwar selten, aber doch manchmal zuschlägt, ist die 
Beschränkung der Eingangssignale (54 bei XC9500XL) für einen Function 
Block.
Als Abhilfe kann man versuchen, diejenigen Pins, deren Gleichungen die 
selben Eingangssignale verwenden (z.B. ein Zähler), in den gleichen 
Function zu legen.

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.