Ich habe intern zwei 128-bit Register. Das Host interface ist 8-bit
breit. Um nun die beiden register schreiben zu können, habe ich folgende
Demux-Struktur (das ganze 2x):
1
ifctrl_busy='0'then
2
ifwr_en_data='1'then
3
casebyte_sel(3downto0)is
4
when"0000"=>data(7downto0)<=wdata;
5
when"0001"=>data(15downto8)<=wdata;
6
when"0010"=>data(23downto16)<=wdata;
7
when"0011"=>data(31downto24)<=wdata;
8
when"0100"=>data(39downto32)<=wdata;
9
when"0101"=>data(47downto40)<=wdata;
10
when"0110"=>data(55downto48)<=wdata;
11
when"0111"=>data(63downto56)<=wdata;
12
when"1000"=>data(71downto64)<=wdata;
13
when"1001"=>data(79downto72)<=wdata;
14
when"1010"=>data(87downto80)<=wdata;
15
when"1011"=>data(95downto88)<=wdata;
16
when"1100"=>data(103downto96)<=wdata;
17
when"1101"=>data(111downto104)<=wdata;
18
when"1110"=>data(119downto112)<=wdata;
19
whenothers=>data(127downto120)<=wdata;
20
endcase;
21
endif;
22
....
23
endif;
Ist es irgendwie möglich, eine solches Verhalten einfacher zu
beschreiben, bzw. die Struktur zu optimieren?
lg Martin
Martin schrieb:> Ist es irgendwie möglich, eine solches Verhalten einfacher zu> beschreiben,
Ja. Siehe
http://www.lothar-miller.de/s9y/archives/65-Vektormanipulation.html> die Struktur zu optimieren?
Du könntest dein 128-Bit Wort in kleinere Happen unterteilen (Bytesel
z.B. nur 2 Bit breit), dann ist nicht vor jedem einzelen Bit ein großer
16:1 Multiplexer, sondern nur ein 4:1 Mux. Allerdings musst du dann
natürlich einen paralellen 4:1 Pfad aufbauen, denn letztlich hast du ja
die 16:1 Zuweisung.
Ob das was bringt zeigt dir dann der RTL-Schaltplan oder die erreichbare
Taktfrequenz/Durchlaufzeit...
Und die Zuweisung an idx natürlich im Körper des Prozesses. Ich krieg
gerade nix hin. Wie auch immer: Xilinx-Tools generieren mir mit dieser
"high-level"-Beschreibung brauchbare Hardware.
Martin schrieb:> Ist es irgendwie möglich, eine solches Verhalten einfacher zu> beschreiben, bzw. die Struktur zu optimieren?
Einen Binärbaum kann man daraus machen. Bringt bei manchen Tools
besseres Timing :-)
Binärbär schrieb:> Einen Binärbaum kann man daraus machen. Bringt bei manchen Tools> besseres Timing :-)
Bei dem oben dargestellten Multiplexer handelt es sich ja um exklusive
(nicht "alternative") Zuweisungen, von daher wird da eigentlich nichts
anderes gebraucht, als eine Handvoll enables für die Teilzuweisungen des
Vektors, also jeweils ein Komparator. Was anders wäre es bei einem MUX
der folgenden Art, dass immer dasselbe Register aus einer von n Optionen
gespeist wird.
Beides sollte wohl jedes Synthesewerkzeug plattdrücken können. Obwohl,
man weiss ja nie :-)
Die Exklusivität spielt bei solchen Zuweisungen keine Rolle,
bei obigen Beispiel ergibt sie sich nur aus der Definition.
Für die Implementierung braucht man je 8Bit-DATA-Slice ein
ENABLE-Signal, das per LUT4 erzeugt werden kann. Dann wird
per DATA-Slice-FF ein LUT4 mit den Signalen ENABLE, WRITE
und WDATA(*) zur Ansteuerung verwendet. Macht also
144 (=16+128) LUT4s und 128 FFs.
Sigi schrieb:> und 128 FFs
Wofür braucht ein Mux ein Flipflop?
Jürgen Schuhmacher schrieb:> Was anders wäre es bei einem MUX der folgenden Art, dass immer dasselbe> Register aus einer von n Optionen gespeist wird.
So ist es aber doch auch: ein Ausgang bekommt das Signal eines von 16
Eingängen. Das Ganze dann 8 mal parallel. Denn es gibt keine
"Vektoroperationen" im FPGA. Es wird jeder einzelne der 128 Eingänge per
Handschlag zum Ausgang durchgereicht. Man braucht also 8 Stück 16:1 Mux,
die zudem noch mit Steuersignalen zu kämpfen haben (hoffent sind das
keine Latches...)
Lothar Miller schrieb:
>So ist es aber doch auch: ein Ausgang bekommt das Signal eines von 16>Eingängen. ..
Sicher?
Einem 8Bit-Slice wird unter einer bestimmten Bedingung byte_sel="xyzw"
WDATA zugewiesen. Trifft diese Bedigung nicht zu, muss etwas anderes
zugewiesen werden, was aber oben im Code nicht erwähnt wird. Irgendwo
wird also ein Latch-Vector oder FF-Vector hängen, daher meine 128 FFs
(ist aber nur eine Vermutung, es sei denn es werden noch 128 Signale
ins FPGA eingeleitet?).
Also kann man sagen, obige Schaltung ist je data-Signal ein 2erMUX.
Möglich, dass wir uns misverstehen, ich wollte nur darauf hinweisen,
dass bei der hiesigen Schaltung (DEMUX) wenig Raum für mangelnde
Optimierung besteht und das anfordernde eher der MUX wäre, wobei auch
der einfach plattgeklopft werden können muss.
Lothar Miller schrieb:> So ist es aber doch auch: ein Ausgang bekommt das Signal eines von 16> Eingängen.
Bei einem MUX ja, bei dem DEMUX oben bekommt jeder Ausgang nur ein
einziges Datensignal.
> Denn es gibt keine "Vektoroperationen" im FPGA.
Gemeint war der "vector" data(128 downto 0) und die Operation, die auf
ihn wirkt.
> Es wird jeder einzelne der 128 Eingänge per> Handschlag zum Ausgang durchgereicht.
So ist es.
> Man braucht also 8 Stück 16:1 Mux
Ich sehe hier nur 128 FFs (im getakteten Fall) mit 128 enables von denen
jeweils 8 zusammen einen Komparatorausgang benutzen - einen von 16
Decodern. Muxen tun die nichts und die 128 FFs fallen bei geschickter
Verdrahtung weiteren Optimierungen zum Opfer. Oder waren wir hier wieder
beim Mux-Fall?
Wenn der Prozess ungetaktet ist und so sieht es ja aus, würde ich
ohnehin nicht versuchen, diese Schaltung partiell optimieren zu wollen,
denn die Funktionalität kann auch noch mit folgender Kombinatorik
zusammengefaltet werden, bevor es in den nächsten Speicher geht.
Ich habe zu dem Thema immer mal wieder Versuche gemacht und gefunden,
dass es bei aktuellen Tools sogar Wurscht ist, ob man If THEN nutzt oder
CASE WHEN. Solange es keinen echten Vorrang gibt, purzelt alles zusammen
und die Schaltung (als Modul formuliert) hat immer denselben
Grössenbedarf.
Änderungen gibt es nur in der Gesamtbetrachtung bei Hinzunahme weiterer
Schaltungsteile, also z.B. bei der Frage, wie denn die enables und
Steuersignale gebildet werden und wie deren Kombinatorik vorher
aussieht. Wenn da FFs drinstecken und sie an anderer Stelle zu ganz
bestimmten Zeiten im Design verwendet werden, kann die Synthese weniger
umbalancieren, als wenn man alles mit Kombinatorik macht und nur davor
und dahinter FFs hat - das timing und die Verteilung offenbleibt.
Dann wirken sich die globalen constraints area / speed am Stärksten aus,
weil die Synthese dann erstmal die gemeinsamen Signale bilden und
registrieren kann, um sie dann mehrfach zu verwenden und dies so, dass
es timing-getrieben optimal passt. Im anderen Falle (area) werden die
Urspünge der enables mit Teilen des Decoders zusammengefasst und in die
LUTs abgebildet. Wie das dann aussieht und welche Terme gebildet werden,
hängt stark von der Decodergrösse ab und den LUT-Breiten im FPGA ab.
Ob man da per Hand bessere Ergebnisse erzielt, als die Synthesetools,
ist äusserst fraglich. Unterschiede gibt es freilich, wenn man sie nur
mal die Ergebnisse von XST und/oder Synplify ansieht.
Jürgen Schuhmacher schrieb:
>Ob man da per Hand bessere Ergebnisse erzielt, als die Synthesetools,>ist äusserst fraglich. Unterschiede gibt es freilich, wenn man sie nur>mal die Ergebnisse von XST und/oder Synplify ansieht.
Also "von Hand" würde ich bei einer LUT4-Architektur 2 LUT4s
je DATA-Bit hintereinanderschalten, bei einer LUT6-Architektur
reicht ein LUT6 je Bit vollkommen aus (ich nehme einfach mal an,
DATA ist als 128-FF-Vector implementiert). Damit kann man in beiden
Fällen das max. Mögliche in Bezug auf Performance und Platz erzielen.
XST/Quartus/Diamond wird das höchstwahrcheinlich nicht erreichen.