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
casereadRamis
4
when'0'=>
5
ram_addr<=ramAddr;
6
whenothers=>
7
ram_addr<=temp_trigger(addresswidth-1downto0);
8
endcase;
9
endprocess;
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ß?
> 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:
Lothar Miller schrieb:
> Du könntest das auch einfach concurrent in einer Zeile beschreiben:>
1
>ram_addr<=ramAddrwhenreadRam='0'elseram_addr<=
2
>temp_trigger(addresswidth-1downto0);
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.
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:
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.
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.
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?
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
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.
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.
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 :).
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)
> 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...
Okay, habe noch 4 Makrozellen freigehabt und mal folgendes gebastelt:
1
libraryIEEE;
2
useIEEE.STD_LOGIC_1164.ALL;
3
useIEEE.numeric_std.ALL;
4
5
entityclkdiv_moduleis
6
Port(clk:inSTD_LOGIC;
7
div:inSTD_LOGIC_VECTOR(1downto0);
8
ena:outSTD_LOGIC);
9
endclkdiv_module;
10
11
architectureBehavioralofclkdiv_moduleis
12
signalstlv_cnt:UNSIGNED(2downto0);
13
begin
14
divider:process
15
begin
16
waituntilrising_edge(clk);
17
stlv_cnt<=stlv_cnt+1;
18
casedivis
19
when"00"=>
20
ena<='1';
21
when"01"=>
22
ena<=stlv_cnt(0);
23
when"10"=>
24
ena<=stlv_cnt(0)ANDNOTstlv_cnt(1);
25
whenothers=>
26
ena<=stlv_cnt(0)ANDstlv_cnt(1)ANDstlv_cnt(2);
27
endcase;
28
endprocess;
29
endBehavioral;
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?
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?
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.
@ 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
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.
> 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.