Hallo miteinander, ich verzweifle langsam ein bisschen mit meinem MAX1000 board bzw. Quartus. Ich wollte ein bisschen mit einer Carry-Chain herumexperimentieren, bekomme aber einfach nicht Quartus dazu mir die Logikzellen so zusammenzusetzen wie ich es haben möchte. Es geht mir dabei eher ums Prinzip als um eine wirkliche Anwendung. Haben möchte ich folgendes: Eine Kette von Logikzellen bei denen nichts weiter passiert als den Carry-In an Carry-Out durchzuschleifen. Also so wie im Bild. Ich schaffe es einfach nicht Quartus zu sagen, dass er 'einfach nur' LEs mit dieser Konfiguration erzeugen soll. Ich habe viele verschiedene Wege über eine Addition von 'signed' bis zu 'carry_sum' und 'carry' primitives mit allen erdenklichen Einstellungen der Synthese ausprobiert. Das funktioniert allerdings nur mir vielen Einschränkungen und ich scheine kaum Einfluss haben zu können wie und was Quartus wegoptimisiert. Beispielsweise werden alle Ketten kleiner gleich vier Elementen in eine LE zusammengefasst, und zusätzlich wird eine gleiche Anzahl an Konstanten benötigt. Gibt es da eine Möglichkeit bessere Kontrolle über die Erzeugung der LEs zu haben?
Klaus schrieb: > Gibt es da eine Möglichkeit bessere Kontrolle über die Erzeugung der LEs > zu haben? Optimierung abschalten, global und/oder lokal. Für xilinx gibt es vhdl attribute 'dont_touch' und 'keep' o.ä.. Bei Quartus mag es Ähnliches geben. https://www.intel.com/content/www/us/en/programmable/quartushelp/17.0/hdl/vhdl/vhdl_file_dir_preserve.htm https://stackoverflow.com/questions/24712976/prevent-compiler-from-optimizing-logic-away Direkte Instanzierung von primitiven ist auch ne Option: https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/ug/ug_low_level.pdf https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/ug/ug_low_level.pdf
Klaus schrieb: > Gibt es da eine Möglichkeit bessere Kontrolle über die Erzeugung der LEs > zu haben? Ja, kann für Altera, Xilinx und Lattice folgendermassen gemacht werden: Zu jeder Familie (der einzelnen Hersteller) gibt es Bibliotheken für alle Bausteine (IO, RAM, LCELL, etc.), die sich problemlos per Std.Instantiierung in VHDL/Verilog in ein Design einbinden lassen. Für z.B. LEs kannst du sogar die LUT4/LUT6/etc-Funktion frei wählen. Zusätzlich gibt es bei allen 3 Herstellern sogenannte Location-Constraints, teils mit relativer, teils mit absoluter Positionierung. Damit kannst du dann die Lage "deiner" LEs relativ frei wählen. Das ganze hatte ich in der Vergangenheit schon ofter für alle 3 Hersteller gemacht (kleine DSP-Units mit beliebigen Funktionen), hatte immer problemlos funktioniert.
C. A. Rotwang schrieb: > Optimierung abschalten, global und/oder lokal. Für xilinx gibt es vhdl > attribute 'dont_touch' und 'keep' o.ä.. Bei Quartus mag es Ähnliches > geben. Das habe ich auch in allen möglichen Variationen versucht. Wenn ich im unteren VHDL code beispielsweise 'carry_transfer' das Attribut keep=true zuweise, macht Quartus aus der Carry Chain eine einfache Folge von Buffern. Sigi schrieb: > Zu jeder Familie (der einzelnen Hersteller) gibt es Bibliotheken > für alle Bausteine (IO, RAM, LCELL, etc.) LCELL hatte ich auch schon gesehen, allerdings gibt es da nur einen Ein- und Ausgang. Ich bin mir nicht sicher, ob ich überhaupt richtig verstanden habe wie man die Primitives wie carry_sum benutzen soll. Folgendes versuche ich zu synthetisieren:
1 | architecture primitive of delay_line is |
2 | component carry_sum |
3 | port ( |
4 | sin : in std_logic; |
5 | cin : in std_logic; |
6 | sout : out std_logic; |
7 | cout : out std_logic ); |
8 | end component; |
9 | signal carry_transfer: std_logic_vector(LINE_WIDTH downto 0); |
10 | begin
|
11 | carry_transfer(0) <= INPUT; |
12 | |
13 | f: for i in 1 to LINE_WIDTH generate |
14 | c: carry_sum port map (sin => '1', |
15 | cin => carry_transfer(i-1), |
16 | cout => carry_transfer(i)); |
17 | end generate; |
18 | |
19 | OUTPUT <= carry_transfer(LINE_WIDTH); |
20 | end; |
Im RTL-Viewer sieht es wie im angehängten Bild aus, in det Technology Map ist es dann vollständig verschwunden. Ich habe alle auswählbaren Optimisierungseinstellungen durchprobiert, nichts hat geholfen. Gibt es noch andere außer denen unter "Settings->Compiler Settings->Advanced Settings"? ... schrieb: > Einfach die LEs im Floorplaneditor verbinden. So habe ich das mit dem Bild im ersten Post gemacht, allerdings ist dann nach erneutem Kompilieren alles wieder weg.
Klaus schrieb: > Gibt es > noch andere außer denen unter "Settings->Compiler Settings->Advanced > Settings"? Da gibt es zwei Klassen, Fitter und Synthesis, da muss man wohl beide durchklopfen. (Screenshots als 'Inspiration' im Anhang). Und dann gibt es noch die tcl command line scripts (quartus_map, Quartus_fit, die sollten, müßen aber nicht gleich mit denen von der GUI sein. https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/manual/tclscriptrefmnl.pdf Mit der script-sprache könnte es möglich sein Verbindungen und cells anzulegen (connect_chain) repektive zu ändern (ohne VHDL und Co) und dann die Netzliste rauszuschreiben. Das ist dann aber richtig Low level FPGA-designen. Fast sowie damals Hexcodes im Memory per System-Monitor zu hacken. Darüberhinaus ist Quartus nicht das einzige synthese-tool für Cyclone, allerdings wohl das einzig kostenlose.
Nimm die fiftyfivenm_lcell_comb, mit dont_touch => "on" wird die nicht wegoptimiert:
1 | component fiftyfivenm_lcell_comb |
2 | generic ( |
3 | dont_touch : string := "off"; |
4 | lpm_hint : string := "UNUSED"; |
5 | lpm_type : string := "fiftyfivenm_lcell_comb"; |
6 | lut_mask : std_logic_vector(15 downto 0) := "0000000000000000"; |
7 | sum_lutc_input : string := "datac" ); |
8 | port( |
9 | cin : in std_logic := '0'; |
10 | combout : out std_logic; |
11 | cout : out std_logic; |
12 | dataa : in std_logic := '0'; |
13 | datab : in std_logic := '0'; |
14 | datac : in std_logic := '0'; |
15 | datad : in std_logic := '0' |
16 | );
|
17 | end component; |
bzw.
1 | library wysiwyg; |
2 | use wysiwyg.fiftyfivenm_components.all; |
Damit kann man wunderbar Delay-Lines bauen, Ergebnis war ein TDC mit niedrigen 2stelligen Picosekunden RMS. Bei den Details begibst Du dich da aber auf undokumentiertes Low-Low-(Low-)Level Gebiet, aber es geht dir ja nur ums Prinzip... (Der FAE sagte das geht nicht...)
Klaus schrieb: > LCELL hatte ich auch schon gesehen, allerdings gibt es da nur einen Ein- > und Ausgang. ... und natürlich noch eine Hand voll Generics. Was hast du denn noch erwartet? Die Bausteine werden wie Komponenten in VHDL/Verilog in dein Design eingebunden, mehr als IOs (+Generics) sind also nicht erforderlich. Vlt aber eine kleine Übung für dich, damit du dir eine Kette im ChipPlanner/Floorplanner/etc. anschauen kannst: Setze ein neues Projekt auf, schreib eine kleine Komponente mit 2*4 Input Pins (für Input-Vektoren din1,din2 der Länge 4) und 5 Output Pins (für Output-Vektor dout der Länge 5) und addiere dout=din1+din2. Im ChipPlanner siehst du dann schon mal die LEs mit den Verbindungen untereinander und den entsprechenden Settings für eigene Generics in den LCELL-Komponenten. Was bei deinem Beispiel auch wichtig ist: du verwendest keine LCELL-Ausgaben wie z.B. REGOUT/COMBOUT (ausser COUT), von daher sieht der Synthesizer nur eine lange Signalkette, die er durch Wegoptimieren zu einer kurzen/direkten Verbindung macht. Von daher sind deine Komponenten wegoptimiert. Um wie Oben von mir beschrieben die Komponenten zu instantiieren und per Location-Constraints einzubinden sind nur die Instatiierungen in HDL und die Constraints in den entsprechenden Constraints-Files (z.B. QSF-File) notwendig, die Beschreibung dazu steht in den Manuals. Komplizierte Settings in Quartus (oder auch ISE/LatticeDiamond) habe ich nie gemacht.
> allerdings ist dann nach erneutem Kompilieren alles wieder weg.
Das muss man als Fieldchange per Changemanagement hinzufuegen.
ich schrieb: > Nimm die fiftyfivenm_lcell_comb, mit dont_touch => "on" wird die > nicht > wegoptimiert: Oh man, du bist mein Held! Genau das habe ich gesucht. Puhh, wie viele Stunden ich mich deswegen schon durch das Internet gewühlt habe. Sigi schrieb: > ... und natürlich noch eine Hand voll Generics. > Was hast du denn noch erwartet? Die Bausteine werden > wie Komponenten in VHDL/Verilog in dein Design eingebunden, > mehr als IOs (+Generics) sind also nicht erforderlich. > > Vlt aber eine kleine Übung für dich, damit du dir eine > Kette im ChipPlanner/Floorplanner/etc. anschauen kannst: > Setze ein neues Projekt auf, schreib eine kleine Komponente > mit 2*4 Input Pins (für Input-Vektoren din1,din2 der Länge 4) > und 5 Output Pins (für Output-Vektor dout der Länge 5) und > addiere dout=din1+din2. Im ChipPlanner siehst du dann schon > mal die LEs mit den Verbindungen untereinander und den > entsprechenden Settings für eigene Generics in den > LCELL-Komponenten. Ich weiß nicht, ob ich dich richtig verstehe. Meinst du die Settings wie aus dem Bild in meinem ersten Post? Ich hatte nur die LCELL von der Intel Webseite gefunden, die nur einen Ein- und Ausgang hat, aber keine Generics. Oder meinen wir verschiedene LCELLs?
Klaus schrieb: > Ich hatte nur die LCELL von der > Intel Webseite gefunden, die nur einen Ein- und Ausgang hat, aber keine > Generics. Oder meinen wir verschiedene LCELLs? Ah, ok, daher unser Missverständnis. Ich hatte mich schon über deine "kurze" PortMap-Liste gewundert. Hier mal, wie von "ich", eine LCELL vom CycloneV (aus QuartusII 13.1,wysiwyg Verzeichnis):
1 | component cyclonev_lcell_comb |
2 | generic ( |
3 | dont_touch : string := "off"; |
4 | extended_lut : string := "off"; |
5 | lpm_hint : string := "UNUSED"; |
6 | lpm_type : string := "cyclonev_lcell_comb"; |
7 | lut_mask : std_logic_vector(63 downto 0) := "1111111111111111111111111111111111111111111111111111111111111111"; |
8 | shared_arith : string := "off" ); |
9 | port( |
10 | cin : in std_logic := '0'; |
11 | combout : out std_logic; |
12 | cout : out std_logic; |
13 | dataa : in std_logic := '0'; |
14 | datab : in std_logic := '0'; |
15 | datac : in std_logic := '0'; |
16 | datad : in std_logic := '0'; |
17 | datae : in std_logic := '0'; |
18 | dataf : in std_logic := '0'; |
19 | datag : in std_logic := '0'; |
20 | sharein : in std_logic := '0'; |
21 | shareout : out std_logic; |
22 | sumout : out std_logic |
23 | );
|
24 | end component; |
Du siehst ja den Unterschied zu "fiftyfivenm_lcell_comb", von daher, nimm immer die Componente deiner Familie. Die Properties/Settings/Modes im Bild aus deinem ersten Posting lassen sich damit sofort in den Generics wiederfinden. (noch kleiner Tipp: wenn du "deine" Wunsch-LUT-Maske setzt, dann kann Quartus deine Ports A,B,C,D,etc und die zugehörige Maske permutieren. Als Folge siehst du dann unter Properties eine scheinbar komplett andere Maske, also nicht wundern) Und deswegen habe ich dir ja das kleine Projekt empfohlen. Öffne dieses in einem 2. QUartus-Fenster, dann hast du zu deinem eigentlichen Projekt immer eine schnelle Vergleichsmöglichkeit.
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.