Hi Leutz!
Ich habe mir eine Lookup Table für eine DDS geschrieben, diese
beinhaltet einen Sinus in 20Bit Breite. Leider schmeißt mir mein Fitter
das Teil nicht in den BlockRAM, sondern nutzt Logikeinheiten dafür. Mich
wundert das verhalten, weil bei einem getakteten Zugriff doch eigentlich
der BlockRAM genutzt werden sollte? Eventuell sieht ja einer den Fehler
:)
Das ganze wird auf einen MAX10 gepackt...
Ich hatte neulich das gleiche Problem. Bei mir war die Löäsung die
folgende:
Irgendwie hatte Quartus nicht genau mitbekommen, welches MAX10 Device
ich verwende. Daraufhin ging Quartus davon aus, dass ich ein "Compact"
Device habe. Diese können bei der Configuration keine ROM
Initialisierung. Draufhin hat Quartus konsequenterweise darauf
verzichtet, ROM-Tabellen zu verwenden.
Jetzt hab ich den Device-Typ offensichtlich richtig eingesstellt und
alle Methoden funktionieren jetzt vollautomatisch mit ROM und
Initialisierung.
Frage: Arbeitest Du zufällig mit dem MAX1000 Board?
Ich würde aus der Funktion eine impure-Funktion machen:
1
impurefunctioninit_ramreturnmemory_t...
Marcel D. schrieb:> 20Bit Breite. Leider schmeißt mir mein Fitter> das Teil nicht in den BlockRAM
Wie groß sind denn die BlockRAMs in Deinem MAX10? Bei Xilinx sind die
üblicherweise 18 (oder 36) Bit breit, da wäre dann 20 Bit eher
suboptimal.
Duke
Duke Scarring schrieb:> Wie groß sind denn die BlockRAMs in Deinem MAX10? Bei Xilinx sind die> üblicherweise 18 (oder 36) Bit breit, da wäre dann 20 Bit eher> suboptimal.
Laut Datenblatt kann der BRAM wohl nur bestimmte Größen und meine 20Bit
gehören nicht dazu. Werde wohl meine LUT auf 18 Bit runter schrauben
müssen um in den Genuss von BRAM zu kommen, aber ich nutze einen 20 Bit
DAC...
BTW, wo liegt der Unterschied zwischen pure und impure functions?
Marcel D. schrieb:> Laut Datenblatt kann der BRAM wohl nur bestimmte Größen und meine 20Bit> gehören nicht dazu. Werde wohl meine LUT auf 18 Bit runter schrauben> müssen um in den Genuss von BRAM zu kommen, aber ich nutze einen 20 Bit> DAC...
wer hält dich davon ab, (z.B.) zwei jeweils 10 bit breite RAMs zu
erzeugen?
Markus F. schrieb:> wer hält dich davon ab, (z.B.) zwei jeweils 10 bit breite RAMs zu> erzeugen?
Eigentlich sollte das der Synthetisierer/Fitter für mich machen oder
nicht?
Habe meine Implementierung mit dem Template im Quartus verglichen,
eigentlich sind sie identisch was das Auslesen der Werte angeht.
Marcel D. schrieb:> BTW, wo liegt der Unterschied zwischen pure und impure functions?
1
The value returned by an impure function can depend on items other than just its input parameters (e.g.shared variables).
Ich weiß nicht, ob das wirklich relevant ist.
Marcel D. schrieb:> Eigentlich sollte das der Synthetisierer/Fitter für mich machen oder> nicht?
Ja, eigentlich schon, aber bei manchen Dingen muß man nachhelfen.
Marcel D. schrieb:> ich nutze einen 20 Bit DAC...
Du könntest die zwei Bits durch Interpolation ermitteln. Oder erstmal
auf "00" setzen.
Duke
Duke Scarring schrieb:> Marcel D. schrieb:>> ich nutze einen 20 Bit DAC...> Du könntest die zwei Bits durch Interpolation ermitteln. Oder erstmal> auf "00" setzen.
Habe die LUT auf 18 Bit verkleinert und die oberen Bits auf GND gesetzt,
dennoch schmeißt er mir alles in Logikeinheiten :-/
Liegt das eventuell an den math-funktionen?
Quartus scheint ein wenig pingelig, was den MAX10 angeht.
Ich habe das gerade mal ausprobiert: intern scheint Quartus aus deiner
Initialisierungsfunktion eine .mif-Datei zu erzeugen und mit der den
Speicher initialisieren zu wollen (jedenfalls liegt im .db-Verzeichnis
eine). Bei der Synthese kam bei mir allerdings anschliessend tatsächlich
auch erst die Fehlermeldung ".mif files are not supported on this
device" und das ROM wurde final ein Gattergrab.
Es tut aber alles so wie gedacht, wenn in "Device->Device and Pin
Options...->Internal Configuration" "Single Uncompressed Image with
Memory Initialization ..." eingestellt ist. Das funktioniert natürlich
nur bei den Käfern, die das auch unterstützen (offensichtlich nicht alle
MAX10).
chris schrieb:> Wäre für eine Sinus-Tabelle ROM nicht besser als RAM?
Das "echte" MAX10 ROM steht - zumindest soweit ich weiss - nur als
Avalon memory mapped interface IP zur Verfügung. Das ist von VHDL-Seite
aus halt nicht ganz so einfach zu greifen wie Block RAM.
Marcel D. schrieb:> Duke Scarring schrieb:>> Wie groß sind denn die BlockRAMs in Deinem MAX10? Bei Xilinx sind die>> üblicherweise 18 (oder 36) Bit breit, da wäre dann 20 Bit eher>> suboptimal.>> Laut Datenblatt kann der BRAM wohl nur bestimmte Größen und meine 20Bit> gehören nicht dazu. Werde wohl meine LUT auf 18 Bit runter schrauben> müssen um in den Genuss von BRAM zu kommen, aber ich nutze einen 20 Bit> DAC...
Denke daran, du musst das Vorzeichenbit zu Füllen benutzen
und nicht einfach nur Nullen, sonst gibt's einen Fehler von
fast einem LSB.
>> BTW, wo liegt der Unterschied zwischen pure und impure functions?
pure functions benutzen nur Angaben aus der Parameterliste
zu Errechnung des Resultats. Die Resultate sind überall und
jedesmal exakt gleich, ganz egal was sich in der Umgebung abspielt.
impure functions können auch globale inputs benutzen, z.B.
das Datum oder eine Eingabezeile. Ich glaube, das gilt auch
für outputs, die am Rückgabewert vorbei Information nach aussen mogeln,
im Stil wie writeline() oder so. Ich musste jedenfalls schon functions
als impure deklarieren, nur wegen Testausgaben.
VHDL nervt manchmal ganz grauslig.
---
Wenn Du das RAM als constant statt als variable deklarierst,
hilft das? Sind diese Blockrams mit einer Pipelinestufe zufrieden?
----
Es würde mich übrigens interessieren, ob meine Tabelle
aus dem anderen thread auch mit Quartus funktioniert.
Ich hätte Lust, die Pferde zu wechseln.
Gruß, Gerhard
Edi M. schrieb:> Entscheidende Frage: (für mich): Ist die so erzeugte Struktur kleiner,> als das Ram?
Wenn man freie RAMs hat, ist die Lösung aus Gattern grundsätzlich
größer.
Und sie besteht aus lauter Funktionen mit sehr vielen Eingängen,
so dass typisch mehrere kombinatorische Gatter in Serie gebraucht
werden. Das schlägt sich natürlich auf die Geschwindigkeit.
Bei der Lösung auf opencores kannst du einfach die Zahl der
Pipelinestufen auf 0 setzen und den großen Topf Gattersuppe
begutachten, der vom Synthesizer dann erzeugt wird.
Da wird "sea of gates" ganz erschreckend real.
Gruß, Gerhard
Ich denke die Idee mit den Device Settings war die Richtige, nun ist
laut Synthese recht viel im RAM und meine LEs nur zu 19% belegt, statt
54% wie zuvor. Jedoch bekomme ich nun eine Fehlermeldung
1
Error (23035): Tcl error: Authorized application C:\INTELF~2\17.0\quartus\bin64\jtagserver.exe is enabled in the firewall.
2
]2;Altera Nios II EDS 17.0 [gcc4]Info: *******************************************************************
3
Info: Running Quartus Prime Convert_programming_file
4
Info: Version 17.0.0 Build 595 04/25/2017 SJ Lite Edition
5
Info: Copyright (C) 2017 Intel Corporation. All rights reserved.
6
Info: Your use of Intel Corporation's design tools, logic functions
7
Info: and other software and tools, and its AMPP partner logic
8
Info: functions, and any output files from any of the foregoing
9
Info: (including device programming or simulation files), and any
10
Info: associated documentation or information are expressly subject
11
Info: to the terms and conditions of the Intel Program License
12
Info: Subscription Agreement, the Intel Quartus Prime License Agreement,
13
Info: the Intel MegaCore Function License Agreement, or other
14
Info: applicable license agreement, including, without limitation,
15
Info: that your use is for the sole purpose of programming logic
16
Info: devices manufactured by Intel and sold by Intel or its
17
Info: authorized distributors. Please refer to the applicable
18
Info: agreement for further details.
19
Info: Processing started: Thu Oct 12 07:34:23 2017
20
Info: Command: quartus_cpf -c MCS2MAX10.cof
21
The compiled configuration mode Single Internal Compressed Image with ERAM does not support multiple pages
22
Error: Quartus Prime Convert_programming_file was unsuccessful. 0 errors, 0 warnings
23
Error: Peak virtual memory: 314 megabytes
24
Error: Processing ended: Thu Oct 12 07:34:24 2017
25
Error: Elapsed time: 00:00:01
26
Error: Total CPU time (on all processors): 00:00:01
27
cp: cannot stat 'files/mcs2max10_cfm1_auto.rpd': No such file or directory
28
cp: cannot stat 'files/MCS2MAX10.map': No such file or directory
29
cp: cannot stat 'files/MCS2MAX10.pof': No such file or directory