www.mikrocontroller.net

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


Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.
process(ramAddr, readRam, temp_trigger)
begin
 case readRam is
  when '0' =>
   ram_addr <= ramAddr;
  when others =>
   ram_addr <= temp_trigger(addresswidth-1 downto 0);
 end case;
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ß?

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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:
   ram_addr <= ramAddr when readRam='0' else ram_addr <= temp_trigger(addresswidth-1 downto 0);

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lothar Miller schrieb:
> Du könntest das auch einfach concurrent in einer Zeile beschreiben:
>
>    ram_addr <= ramAddr when readRam='0' else ram_addr <=
> temp_trigger(addresswidth-1 downto 0);
> 
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.

Autor: Läubi .. (laeubi) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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:
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.
process
  begin
    wait until rising_edge(clk);
    case readRam is
      when '0' =>
        ram_addr <= ramAddr;
      when others =>
        ram_addr <= temp_trigger(addresswidth-1 downto 0);
    end case;
  end process;

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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
c <= a(23) and b(1);
 braucht eine Makrozelle. Genauso braucht eine Funktion wie
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.

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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_s...

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

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael schrieb:
> http://www.xilinx.com/support/documentation/data_s...
>
> 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:
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.
Each XC9500XL macrocell may be individually configured
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

Autor: Iulius (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Michael (Gast)
Datum:

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

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 :).

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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)

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was ich mich jezt allerdings frage:

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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Okay, habe noch 4 Makrozellen freigehabt und mal folgendes gebastelt:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;

entity clkdiv_module is
    Port ( clk : in  STD_LOGIC;
           div : in  STD_LOGIC_VECTOR (1 downto 0);
           ena : out  STD_LOGIC);
end clkdiv_module;

architecture Behavioral of clkdiv_module is
signal stlv_cnt : UNSIGNED(2 downto 0); 
begin
    divider: process
    begin
        wait until rising_edge(clk);
        stlv_cnt <= stlv_cnt + 1;
        case div is
            when "00" => 
                ena <= '1';
            when "01" =>
                ena <= stlv_cnt(0);
            when "10" =>
                ena <= stlv_cnt(0) AND NOT stlv_cnt(1);
            when others => 
                ena <= stlv_cnt(0) AND stlv_cnt(1) AND stlv_cnt(2);
        end case;
    end process;
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?

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

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

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Chip viewer.

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Klaus Falser (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.