Hallo, ich habe ein Problem wie ich ressourcenschonend ein Problem in VHDL modellieren kann. Auch wenn das Beispiel keinen richtigen Sinn macht, so enthält es die Problemstellung: Ich habe eine 8k RAM Komponente mit 1 Bit Breite (also 13 Bit Adressen) in einem Altera Cyclone I (EP1C3T100). Das FPGA taktet mit 50MHz. In dieses RAM müssen 16 Zufallsgeneratoren so etwa alle 50us-100us ein Bit schreiben, es steht also genügend Zeit zur Verfügung. Auch der Zeitpunkt des Schreibens ist rein zufällig, so daß es ganz selten vorkommen kann, daß zwei Generatoren gleichzeitig schreiben wollen. Interface des RAMs: (alles gleichzeitig und für genau einen Clock aktiv) data : in std_logic; write_pulse : in_logic; address : in std_logic_vector ( 12 downto 0); Wenn zwei oder mehrere Zufallsgeneratoren gleichzeitig schreiben wollen, reicht es aus wenn nur einer davon tatsächlich schreibt und die anderen ignoriert werden. Es muß auch keine Logik geben daß beim nächsten mal ein anderer Priorität erhält. Das müßte ein einfacher Prioritätsencoder sein. Das selbe Problem besteht beim Lesen. Jeder der Zufallsgeneratoren soll aus dem RAM lesen können. Bei gleichzeitigem Zugriff zweier oder mehrerer soll an einen der tatsächlich gelesene Wert geliefert werden, an alle anderen einfach eine '0' Interface des RAMs: data : out std_logic; read_pulse : in std_logic; address : in std_logic_vector ( 12 downto 0); Meine Frage ist wie modelliere ich hier einen Multiplexer oder Dispatcher oder sowas, ohne daß er mir massenweise LE schluckt? Ich befürche hier sonst schon für das Adressregister je Seite 16x13=208 LE schluckt. Mir täten ja Latches oder Tristates reichen. Mit realen Komponenten würde ich z.B. die Write-Pulse auf einen Prioritätsencoder geben, und daraus die Enable-Signale der Ausgangslatches der Generatoren geben (oder so etwa...) Oder brauch ich da nichts zu befürchten wenn ich den Multiplexer als rein kombinatorischen Prozess aufbaue? Danke für die Diskussion! Günter (dl4mea)
schreiben: - schiebereigster 16 bit breit, eine 1 wandert je takt immer im kreis durch, rest nullen. - muxe (adresse, daten, write enable) wechseln auf den generator mit der nummer des 1er bits im sr. - jeder generator bekommt das entsprechende bit vom sr als leitung rausgeführt um zu erkennen das er schreiben durfte. daraufhin kann write enable wieder entfernt werden lesen: - gleiches schieberegister verwenden, adress und read enable muxe entsprechend anpassen - wenn generator in seiner leitung vom sr erkennt das er aktiviert wurde und er lesen wollte, dann liegen im nächsten takt die daten an Mit dieser Logik solltest du kaum ressourcenverbrauch haben (5 LUTs pro mux-bit -> vielleicht 200 Luts) und verlierst zudem keine schreib- oder leseanforderung. wenn ne sparsamere variante gibt würde die mich echt interessieren. sorry für fehlende großschreibung, bin müde.
Iulius schrieb: > - schiebereigster 16 bit breit, eine 1 wandert je takt immer im kreis > durch, rest nullen. Hallo, danke erst mal für die Antwort. Nun, wenn ich da tatsächlich einen Handshake zwischen Zufallsgenerator und Multiplexer einbauen würde, dann kann ich gleich die Adresse seriell übertragen, und spare ziemlich Ressourcen. Wäre auch eine Idee. Mir ging es mehr darum einfach den Schreibbefehl anzulegen, zu hoffen dass gerade kein anderer schreibt, und als Multiplexer auf irgendwelche Funktionalität des Senders, z.B. HIGH-Z oder ähnliches, aufzubauen. Geht sowas? Ciao, Günter
tristate im FPGA hast du aber nicht zur Verfügung. >> dann kann ich gleich die Adresse seriell >> übertragen, und spare ziemlich Ressourcen ob die (de-)serializer logik weniger verbrauch als der mux müsste man probieren, wirklich glauben kann ichs jedoch nicht.
> Auch der Zeitpunkt des Schreibens ist rein zufällig, > so daß es ganz selten vorkommen kann, > daß zwei Generatoren gleichzeitig schreiben wollen. Aus der Praxis gesehen würde ich das herumdrehen: es werden andauernd mindestens 2 der 16 Generatoren gleichzeitig schreiben wollen. So wird das Gesetz von Murphy sich auf jeden Fall in deinem Fall auswirken... ;-) Was willst du denn bauen? Einen super-zufälligen-Zufallsgenerator? Wie implementiertst du die 16 Zufallsgeneratoren? Wie initialisierst du diese 16 Generatoren? Und zum Schluss: ist das Ergebnis der 16 Generatoren wirklich soviel zufälliger als wenn du 1 großes LFSR verwendest? Falls ja: kannst du das begründen?
Lothar Miller schrieb: > Was willst du denn bauen? Einen super-zufälligen-Zufallsgenerator? Hallo Lothar, wie ich schon meinte, das ist nur ein Beispiel für die reale Anwendung. In der Realität sind es Empfänger, die nacheinander auf den ankommenden Datenstrom synchronisieren, und die CRC des Frames wird notiert und zur weiteren Verifikation auf Duplikate benutzt. Also: CRC wird als Adresse verwendet, und in einem RAM dann ein Bit gesetzt, welches später zum Check abgefragt wird. Und wenn dann doch ein doppeltes durchrutscht (sprich: das Bit an der entsprechenden Adresse wurde wegen Duplikat nicht gesetzt), dann macht das auch nichts. Weiterhin: Mir geht es darum wie ich ich den Ressourcenverbrauch des Adressmultiplexers so klein wie möglich halten kann. Ciao, Günter
Schreiben: Du wirst also von jedem der Generatoren eine CRC und ein Valid-Signal erhalten, das für jeweils 1 Taktzyklus aktiv ist. Dann wird an diese Adresse eine '1' geschrieben. Ich würde den "klassischen" Ansatz einfach mal ausprobieren: if valid1='1' then address <= CRC1; elsif valid2='1' then address <= CRC2; elsif valid3='1' then .... Lesen: Hier muß ja von den Generatoren eine Adresse und ein Read-Request kommen. Der Aufbau wird ähnlich sein: if rdreq1='1' then address <= addr1; elsif rdreq2='1' then address <= addr2; .... data1 <= (others=>'0'); data2 <= (others=>'0'); data3 <= (others=>'0'); : if rdreq1='1' then data1 <= data; elsif rdreq2='1' then data2 <= data; .... > Mir täten ja ... Tristates reichen. Das gibt es innerhalb eines FPGAs nicht. Alle Tristates werden entweder in Multiplexer umgewandelt, oder als Fehler gemeldet. > Ich befürche hier sonst schon für das Adressregister > je Seite 16x13=208 LE schluckt. Vermutlich nicht, aber: warum probierst du das nicht einfach aus?
Lothar Miller schrieb: > Vermutlich nicht, aber: warum probierst du das nicht einfach aus? Wie kann ich eigentlich den Ressourcenverbrauch einer einzelnen Teilfunktion, z.b. einer instanzierten Entity oder eines Prozesses herausfinden? In 'C' finde ich das im Mapfile. Geht das in VHDL eventuell genauso?. Ich hab jetzt bei einem RX so etwa 300 LE mehr gesehen, da sieht auch irgendwie vernünftig aus. Ciao, Günter
>> Wie kann ich eigentlich den Ressourcenverbrauch einer einzelnen >> Teilfunktion, z.b. einer instanzierten Entity oder eines Prozesses >> herausfinden? Da du Altera nutzt: Designflow in quartus durchlaufen lassen, dann links oben in im project navigator fenster auf hierarchy schalten(wenns nicht eh schon dort steht) und den baum aufklappen. Dort steht fein säuberlich jede Resource aufgelistet. bsp: http://quartushelp.altera.com/9.1/mergedProjects/global/image/pjn_image_hierarchy_tab.gif
Und bei Xilinx setzt du einfach das entsprechende Modul temporär als Top-Level Entity und lässt es synthetisieren
Geht auch einfacher: Beim Designflow bei Map Properties den Haken bei -detail reinmachen und dann kannst du bei den Reports den Module Level Utilization angucken.
Iulius schrieb: > Dort steht fein säuberlich jede Resource aufgelistet. Hallo, so, dann mal vielen Dank, es pendelt sich schon langsam ein. Danke für die geniale Hilfe! Jetzt nur noch die dumme Frage: ich seh hier häufig die Gatterrealsierung bestimmter VHDL-Konstrukte abgebildet, und zwar mit schwarzem Hintergrund. Damit ist sicher nicht "Tools"-"Netlist Viewers"-"RTL Viewer" gemeint. Wie geht das denn? Ciao, Günter
> Wie geht das denn? Meinst du sowas wie auf meiner HP: http://www.lothar-miller.de/s9y/categories/44-BCD-Umwandlung Das ist der RTL-Viewer von Xilinx ISE 9.2 In der neuen Version 12 sieht das schon wieder ein wenig anders aus.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.