Forum: FPGA, VHDL & Co. ISE8.1 Projekt wird mit ISE9.1 fehlerhaft implementiert


von Martin K. (mkohler)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,
Ich habe hier nach längerem Suchen nun ein Problem lokalisiert, welches
mir sehr seltsam vorkommt: ein mit ISE8.1 implementiertes Projekt kann
mit ISE9.1  nicht korrekt implementiert werden. Es handelt sich um ein
voll synchrones VHDL Design mit einem DPRAM drin. Der Clock beträgt
48MHz.

Bei der Implementierung werden die definierten Timing constraints
eingehalten, es gibt ein paar Warnings die ich als unkritisch erachte,
aber keine Fehlermeldungen.

Das Verhalten ist nun so, dass die mit ISE8.1 erstellte Version
funktioniert, bei der mit ISE9.1 erstellten Version beim DPRAM Zugriff
irgend etwas schief geht. Was genau führt hier wohl zu weit.

Den VHDL Source Code habe ich mit ModelSIM XE II 5.8c simuliert und
keinerlei Probleme festgestellt. Ich habe jedoch nur "Simulate
Behavioral Model" durchgeführt, da ich bisher davon ausgegangen bin,
dass dies genügt, wenn die genügend scharf eingestellten Timing
Constraints eingehalten werden.

Die Timing Constraints sind wie folgt eingestellt:
# Timing
NET "uC_CLK" TNM_NET = "uC_CLK";
TIMESPEC "TS_uC_CLK" = PERIOD "uC_CLK" 15 ns HIGH 50 %;
OFFSET = IN 5 ns BEFORE "uC_CLK"  ;
OFFSET = OUT 15 ns AFTER "uC_CLK"  ;
TIMESPEC "TS_P2P" = FROM "PADS" TO "PADS" 12 ns;

Das Signal uC_CLK ist ein CLK_OUT vom Controller, das ganze FPGA
arbeitet synchron mit diesem Clock.

Angehängt ist die Log-Ausgabe beim Implementieren des Designs mit ISE8.1

Fragen:
- Hat sonst schon mal jemand ähnlichen Ärger mit unterschiedlichen ISE
Versionen gehabt?
- Auf was muss ich achten, dass Simulation und Realität
übereinstimmen/was habe ich vergessen?
- Habe ich noch Timing Constraints vergessen?

Danke und Gruss,
Martin

von Martin K. (mkohler)


Lesenswert?

Keine Ideen der FPGA Cracks?
Braucht ihr noch weitere Infos?

Gruss, Martin

von Klaus F. (kfalser)


Lesenswert?

Mir erscheint ein wenig seltsam, dass der Takt mit 15 ns spezifiziert 
ist, und dass die Ausgangsdaten erst 15 ns nach dem Takt gültig sein 
müssen. Damit bleibt ja kein Fenster übrig, wo die Daten sauber 
übernommen werden können.

Klaus

von Martin K. (mkohler)


Lesenswert?

Dieser Wert ist unkritisch, da die aus dem FPGA hinausführenden Signale 
nirgends schneller verfügbar sein müssen (keine externen kritischen 
Timings). Das habe ich überprüft.
Ich werde den Wert mal heruntersetzen und schauen was die Implementation 
dazu sagt.

Das löst aber mein ISE Problem noch nicht, denn der im 9.1 nicht 
funktionierende Teil befindet sich definitiv NUR intern, also 
timingmässig nur von PERIOD abhängig. Und da sollte sicher nichts schief 
gehen, da ja PERIOD auf 15ns->66MHz definiert ist, der Systemtakt aber 
nur 48MHz->20.8ns beträgt.

Martin

von Klaus F. (kfalser)


Lesenswert?

Entschuldige, hatte übersehen, dass DPRAM == interner Dual Port BRAM.
Da bewirken die OFFSET OUT constraints natürlich nichts.

Möglichkeiten :
- Alle möglichen Service Packs aufspielen
- ISE 9.2 versuchen
- Ein bischen erzählen, was denn nun genau der Fehler ist.

Grüße
Klaus

von Falk B. (falk)


Lesenswert?

@ Klaus Falser (kfalser)

>- ISE 9.2 versuchen

Oder einfach nur wirklich dann eine neue ISE-Version verwenden, wenn es 
WIRKLICH nötig ist (weil ein neuer Baustein in der alten nicht 
unterstützt wird).

Diesen Versionswahnsinn mach ich schon lange nicht mehr mit.

Never Change a Running System!

MFG
Falk

von Martin K. (mkohler)


Lesenswert?

Danke für die Antworten. Dann wollen wir mal...

Zum "bisschen mehr erzählen":
Das System sieht so aus, dass auf der einen Seite synchron mit einem 
8051er Controller kommuniziert wird (alles am gleichen Takt). Auf der 
anderen Seite befindet sich eine Reihe Digitaler Ein- und Ausgänge (je 
12).
Auf beiden Seiten werden alle Signale abgeclockt (sollten alles IOB FF's 
sein).
Das Modell besteht aus einer ganzen Reihe von Einzelfunktionen, welche 
alle auf Basis der abgecklockten DIO Signale arbeiten und über einen 
internen Bus mit dem externen Controller-Bus verbunden sind.

Eine dieser Einzelfunktionen macht nun Ärger. Dieser sog. "Reader" liest 
über zwei Inputs einen Drehgeber und legt bei Eintreffen von positiven 
oder negativen Flanken auf einem weiteren Eingang (der "Lesespur") die 
aktuelle Drehgeberpotition im DPRAM ab.
Dieser Reader-Teil ist so aufgebaut, dass die Positionserfassungslogik 
nur schreibend auf das DPRAM zugreift, das Interface auf den internen 
Bus auf der anderen Seite nur lesend. Es werden 14Bit-Worte abgelegt, 
das DPRAM ist daher als 16Bit Speicher ausgelegt. Im Speicher sollen nun 
bis zu 512 dieser Datenworte abgelegt werden, was zu einem 256x16bit 
Speicher führt. Auf der Leseseite werden die Daten 32Bit breit 
ausgelesen.

BEEEEPPPP!!!!!

Hier liegt wohl der Hund begraben! Ich habe gerade bemerkt, dass die 
Adressbereiche bei der DPRAM Definition einen Fehler aufweisen!

Heute komme ich nicht mehr dazu, zu prüfen, ob sich da der Fehler 
befindet, aber ich frage mich nun, warum es denn mit der Version 8.1 
funktioniert hat.
Mehr dazu dann wohl nächste Woche.

Gruss, Martin

von Martin K. (mkohler)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,
Da bin ich wieder. Der Fehler ist immer noch vorhanden, die Vermutung im 
letzten Postin hat sich als falsch herausgestellt.

Korrektur der vorherigen Angaben:
" Im Speicher sollen nun bis zu 512 dieser Datenworte abgelegt werden, 
was zu einem 256x16bit Speicher führt."
--> führt natürlich zu einem 512x16Bit Speicher, insgesamt also 1kByte 
pro Spur

Ich poste hier mal den VHDL Code des fraglichen Moduls (siehe Anhang).

Die Funktionsweise:
- Schreiben 16bit Worte auf Seite A, Adressbit AA(1) entscheidet, ob in 
RAM_L  oder RAM_H geschrieben wird
- DA(15..0) schreiben, wenn WEA gesetzt
- lesen 32Bit Worte auf Seite B, zusammengesetzt aus je 16Bit H und L

Version 8.1 erstellt mir daraus zwei Block RAM zu je 256x16, in Version 
9.2 wird nur ein Block RAM zu 256x16 erstellt.

Siehe die nächsten beiden Postings für Details dazu

von Martin K. (mkohler)


Angehängte Dateien:

Lesenswert?

RTL schematic mit ISE 8.1.03i

von Martin K. (mkohler)


Angehängte Dateien:

Lesenswert?

RTL schematic mit ISE 9.2.03i

von Martin K. (mkohler)


Angehängte Dateien:

Lesenswert?

Noch eine weitere Information:
Im Modell sind insgesamt 4 dieser Lesespuren vorhanden, es sollten also 
insgesamt 4kByte Block RAM verwendet werden, aufgeteilt in 8x 256x16Bit.

Die Synthese in 9.2 liefert mir nun im Abschnitt "HDL Synthesis" 
folgende Ausgabe:
1
Synthesizing Unit <ReadThroughRAM>.
2
    Related source file is "//achstinf02/kohlmart/SCM_fox/KMC2600/KUSB/I-O_Flex/FPGA_01/VHDL/READERMemoryReadThroughRAM.vhd".
3
    Found 256x16-bit dual-port RAM <Mram_RAM_L> for signal <RAM_L>.
4
    Found 256x16-bit dual-port RAM <Mram_RAM_H> for signal <RAM_H>.
5
    Found 32-bit tristate buffer for signal <INT_D>.
6
    Found 8-bit register for signal <AB>.
7
    Summary:
8
  inferred   2 RAM(s).
9
  inferred   8 D-type flip-flop(s).
10
  inferred  32 Tristate(s).
11
Unit <ReadThroughRAM> synthesized.
Das wäre noch richtig, es werden für die eine Spur 2x 256x16Bit 
verwendet.
Auch der Synthesis Report sieht gut aus:
1
=========================================================================
2
HDL Synthesis Report
3
4
Macro Statistics
5
# RAMs                                                 : 8
6
 256x16-bit dual-port RAM                              : 8
Und nun kommt folgende Ausgabe bei den "Advanced HDL Synthesis":
1
Loading device for application Rf_Device from file '3s250e.nph' in environment C:\Programme\Xilinx_92i.
2
INFO:Xst:2737 - Unit <ReadThroughRAM> : The RAM <Mram_RAM_L>, combined with <Mram_RAM_H>, will be implemented as a BLOCK RAM, absorbing the following register(s): <AB>.
3
    -----------------------------------------------------------------------
4
    | ram_type           | Block                               |          |
5
    -----------------------------------------------------------------------
6
    | Port A                                                              |
7
    |     aspect ratio   | 256-word x 16-bit                   |          |
8
    |     mode           | write-first                         |          |
9
    |     clkA           | connected to signal <INT_CLK>       | rise     |
10
    |     weA            | connected to signal <AA>            | low      |
11
    |     addrA          | connected to signal <AA>            |          |
12
    |     diA            | connected to signal <DA>            |          |
13
    |     doA            | connected to signal <DB>            |          |
14
    -----------------------------------------------------------------------
15
    | optimisation       | speed                               |          |
16
    -----------------------------------------------------------------------
17
    | Port B                                                              |
18
    |     aspect ratio   | 256-word x 16-bit                   |          |
19
    |     mode           | write-first                         |          |
20
    |     clkB           | connected to signal <INT_CLK>       | rise     |
21
    |     addrB          | connected to signal <INT_REG_A>     |          |
22
    |     doB            | connected to signal <DB>            |          |
23
    -----------------------------------------------------------------------
24
    | optimisation       | speed                               |          |
25
    -----------------------------------------------------------------------

Warum werden hier RAM_L und RAM_H zu einem einzigen Block RAM 256x16Bit 
zusammengefasst? Das darf doch so nicht sein?

Im Anhang befindet sich die Log-Ausgabe, aus welcher ich die obigen 
Angaben entnommen habe.

Sieht jemand, wo das konkrete Problem liegt?
Danke für die Antworten.

von Xenu (Gast)


Lesenswert?

Hier ist wohl tatsächlich ein Bug in der ISE-Software.

So geht es übrigens:

            if (WEA = '1' and AA(1) = '0') then
              RAM_L(conv_integer(AA(9 downto 2))) <= DA(15 downto 0);
            elsif(WEA = '1' and AA(1) = '1') then
              RAM_H(conv_integer(AA(9 downto 2))) <= DA(15 downto 0);
            end if;

von Martin K. (mkohler)


Lesenswert?

Kann das sonst noch jemand bestätigen, dass es ein Fehler in der ISE 
9.2.03i Software ist?

Die Variante von Xenu habe ich nun umgesetzt, die funktioniert.

Können bei Xilinx Fehlermeldungen irgendwie eingespeist werden?

von Kest (Gast)


Lesenswert?

...Weißt Du, wie man BlockRAM instantieert? ;-)

Wenn ja, dann mache es den Xilinx-Tools nicht so schwer, sondern 
instantieere zwei blockrams und nicht irgendwie mit einem Process und 
mehreren Enable-Signalen


      if WEA = '1' then
        if AA(1) = '0' then
          RAM_L(conv_integer(AA(9 downto 2))) <= DA(15 downto 0);
        else
          RAM_H(conv_integer(AA(9 downto 2))) <= DA(15 downto 0);
        end if;
      end if;


Wenn Du alles schön aufsplittest, dann wird es auch funktionieren. Zur 
Zeit ist es wohl für die Tools zu kompliziert, daraus zwei BlockRAMs zu 
machen. Wieso auch? Es kommt ein WRite-Enable Signal und von einem 
Signal wird auch die Adresse abhängen, wo es hin geschrieben wird.

Quartus macht daraus zwar 2 Blockrams, aber es kann genausogut einer 
sein, denn Du hast nur einen SchreibPort und einen Leseport (doppelt so 
groß).

RAM_Type würde ich auch von 0 to 255 definieren und nicht umgekehrt.

Also: kein Fehler in ISE sondern ein Feature  ;-)

Grüße,

Kest

von Martin K. (mkohler)


Lesenswert?

Kest wrote:
> ...Weißt Du, wie man BlockRAM instantieert? ;-)
>
> Wenn ja, dann mache es den Xilinx-Tools nicht so schwer, sondern
> instantieere zwei blockrams und nicht irgendwie mit einem Process und
> mehreren Enable-Signalen

Grund: es wurde mir mal empfohlen, das generisch so zu machen mit dem 
ram_type anstelle des herstellerspezifischen Block RAM Konstrukts.

Wie es Xilinx-spezifisch gemacht werden müsste würde ich wohl wieder 
herausfinden.

Das dem-Tool-so-schwer-machen darf aber so oder so nicht zu einem 
ungültigen Resultat führen, wie es aber in 9.2 geschehen ist.

Gruss, Martin

von Kest (Gast)


Lesenswert?

Gerade "generisch" geht es mit 0 to 255. Ich meinte ja auch nicht 
CoreGen oder so, da hast Du mich falsch verstanden.

Den Grund habe ich Dir genannt: das Resultat ist nicht ungültig sondern 
sehr wohl gültig. So wie ich das sehe, hast Du nur einen Blockram 
implementiert. Punkt. Dass in der anderen Version 2 dabei rausgekommen 
sind liegt daran, dass die Tools "nocht nicht so schlau" waren.

Grüße,
Kest

von Martin K. (mkohler)


Lesenswert?

Es ist mir schon klar, dass das Tool auch nur ein Block RAM machen kann.
Dieses sollte dann aber bitte die korrekte Grösse haben, was es aber 
eben nicht hat.

Ich schreibe mit 10 Adressleitungen (AA9..1) je 16Bit breit ins RAM, das 
ergibt nun mal 1024x8Bit oder 512x16Bit, aber sicher nicht 256x16Bit, so 
wie es ISE9.2 implementiert. Da ist sehr wohl etwas faul.

Oder habe ich jetzt komplett Tomaten auf den Augen??

Gruss, Martin

von Xenu (Gast)


Lesenswert?

Das ist definitiv ein Fehler in der Software, weil er zwei 256x16-RAMs 
auf ein 256x16-RAM zusammenstaucht.

Und in der 8.1er Version ging es ja wohl auch noch.

von Kest (Gast)


Lesenswert?

Nein, kein Fehler! Die VHDL-Beschreibung ist falsch.

Wieso die Größe nicht stimmt, weiß ich nicht.


Grüße,

Kest

von Kest (Gast)


Lesenswert?

Überprüfe, was drumherum passiert. Nicht, dass AA(1) wegsynthetisiert 
wird oder was ähnliches.

Kest

von Martin K. (mkohler)


Lesenswert?

Doch, trotzdem Fehler!
Schaue er bitte das Bild mit schwarzem Hintergrund ein paar Postings 
höher an.
Da sieht man, dass DOA(15:0) und DOB(15:0) zu INT_D(31:0) 
zusammengefasst werden.
Der Data Out Port A hat hier aber definitiv nichts verloren, weil dieser 
ja mit der Schreib-Seite adressiert wird, ich aber mit der Lese-Seite 
INT_REG_A resp. AB adressieren will.

Das im Bild gezeigte Verhalten entspricht genau dem in der Realität 
gemessenen Fehler: Beim Lesen auf INT_D waren die unteren 16Bit immer 
konstant, (da AA zum Zeitpunkt des Auslesens konstant war).

Und noch ein Einwand:
Original:
1
            if WEA = '1' then
2
                if AA(1) = '0' then
3
                    RAM_L(conv_integer(AA(9 downto 2))) <= DA(15 downto 0);
4
                else
5
                    RAM_H(conv_integer(AA(9 downto 2))) <= DA(15 downto 0);
6
                end if;
7
              end if;
korrigiert von Xenu:
1
            if (WEA = '1' and AA(1) = '0') then
2
              RAM_L(conv_integer(AA(9 downto 2))) <= DA(15 downto 0);
3
            elsif(WEA = '1' and AA(1) = '1') then
4
              RAM_H(conv_integer(AA(9 downto 2))) <= DA(15 downto 0);
5
            end if;

Warum sollte die Korrektur von Xenu den Fehler verhindern? Er hat ja nur 
die verschachtelte if-Abfrage anders gestaltet. Die Wahrheitstabelle für 
die Ausführung der einzelnen Statements blieb gleich.

Gruss, Martin

von Kest (Gast)


Lesenswert?

Gut... da muss man analytisch vorgehen ;-)

Zunächst mal, würde ich an Deiner Stelle alles so umschreiben, dass in 
einem IF Zweig jeweils ein BlockRAM adressiert (beschrieben) wird. Ich 
habe jetzt leider keine Möglichkeit selber zu synthetisieren, aber 
eventuell ist STD_LOGIC ein Problem. Was passiert, wenn AA(1)=='Z' ist?

Die Implementation von Xenu ist eben eindeutiger.


Grüße,

Kest

von Kest (Gast)


Lesenswert?

Zum RTL-Bild da oben

wieso steht da 256x16 und dann noch Mal da drunter? Damit wir es besser 
sehen?


Kest

von Martin K. (mkohler)


Lesenswert?

Wenn du mit "nochmal da drunter" die zweite identische Zeile meinst:
Ich schätze, dass die erste Zeile Port A und die zweite Zeile Port B 
angibt, in diesem Fall ist das Block RAM auf beiden Seiten 256x16 
organisiert.
Das wäre richtig, nur bräuchte ich eben zwei davon ;-)

Was willst du "besser sehen"?

von Kest (Gast)


Lesenswert?

Ich schreibe, was ich sehe. Und was ich sehe ist, dass Du in der VHDL 
Datei einen BlockRAM implementierst... Noch Mal langsam:

PortA: da kommen Deine Daten rein (8 Bit Breit). Jeweils Low und Hi 
Bytes... Richtig? Diese werden in einer Zeile zu 16 Bit abgelegt.

PortB: da kommen Deine Daten raus (16 Bit Breit)... Richtig?

Nun erklär mir mal, wieso Du zwei BlockRAMS erwartest? Ich habe ja schon 
gesagt, wieso die Größe nicht stimmt, kapiere ich es (noch) nicht, aber 
wieso nur ein BlockRAM rauskommt schon.


Grüße,

Kest

von Kest (Gast)


Lesenswert?

ups... ein Fehler:
"PortA: da kommen Deine Daten rein (8 Bit Breit)."

sollte 16 Bit Breit heißen


Kest

von Martin K. (mkohler)


Lesenswert?

Kest wrote:
> PortB: da kommen Deine Daten raus (16 Bit Breit)... Richtig?
Fast.

Auf INT_D habe ich schlussendlich einen 32Bit Vektor. Dieser wird 
zusammengesetzt aus den unteren 16Bit aus ram_L und den oberen 16Bit aus 
ram_h.
Ob nun die Synthese ram_L und ram_H in ein einziges Block RAM integriert 
oder nicht ist mir ja prinzipiell wurscht, solange das Resultat der 
Beschreibung entspricht. Aber das tut sie ja eben nicht.

Diese Statements werden nicht so umgesetzt, dass alle 32Bit auf DB von 
INT_REG_A = AB abhängen:
1
    -- RAM Daten auslesen
2
    DB(15 downto 0)  <= RAM_L(conv_integer(AB(9 downto 2)));
3
    DB(31 downto 16) <= RAM_H(conv_integer(AB(9 downto 2)));

Gruss, Martin

von Kest (Gast)


Lesenswert?

Alle Ausgänge hängen doch von AB ab! Weiß gar nicht, was Du meinst.


Kest

von Martin K. (mkohler)


Lesenswert?

Kest wrote:
> Alle Ausgänge hängen doch von AB ab! Weiß gar nicht, was Du meinst.
>
>
> Kest
Du hast meine Beiträge oben schon gelesen, hoffentlich?
Ca. 8 Postings weiter oben habe ich nämlich geschrieben:
"Schaue er bitte das Bild mit schwarzem Hintergrund ein paar Postings
höher an.
Da sieht man, dass DOA(15:0) und DOB(15:0) zu INT_D(31:0) 
zusammengefasst werden. Der Data Out Port A hat hier aber definitiv 
nichts verloren, weil dieser ja mit der Schreib-Seite adressiert wird, 
ich aber mit der Lese-Seite
INT_REG_A resp. AB adressieren will."

Im VHDL-Code hängt, alles von DB ab, ja - sehr scharf erkannt! Bravo. 
Aber das ist ja genau der Punkt! Die Implementation von ISE9.2 stimmt 
nicht mit dem VHDL Code überein, das ist doch genau das, was ich schon 
länger mitzuteilen versuche.

Im VHDL Code ist DB einzig abhängig von jeweils 16Bit aus den zwei 
Arrays ram_H und ram_L, adressiert über AB. Insgesamt also alles Seite 
B, bei mir die Leseseite.
In der Realität (schaue er BITTE nochmals das schwarz hinterlegte Bild!) 
hängt aber DB(31:0) von DOA(15:0) und DOB(15:0) ab.
DB darf aber nicht von der Schreibseite A abhängen, da diese ja nicht 
über AB sondern über AA adressiert wird.

> Weiss gar nicht was du meinst
scheint tatsächlich so zu sein, ja.
Schaus noch mal an und vergleiche den VHDL-Code mit dem schwarz 
hinterlegten RTL Schematic des Moduls.

Und bitte nicht nochmals so fundierte Abklärungen wie im letzten 
Posting.

Gibts sonst noch jemanden hier, der es so sieht wie ich?
Xenu? Ein klärender Beitrag von dir? seufz

von Kest (Gast)


Lesenswert?

Das habe ich schon verstanden und das Bild habe ich auch angeschaut, 
bevor ich gepostet habe.

Mal von der Bezeichnung der POrts abgesehen ist das Bild stimmig:

Eingang: 16 Bit, Ausgang 32 Bit. Wie die Ausgangsports nun tatsächlich 
belegt sind, ist zunächstmal egal (alles Definitionsfrage).

Du baharrst darauf, dass Port B nur von der INT_REG_A abhängig ist. 
Tatsächlich aber sind sowohl Port A, als auch Port B (beide Read Ports) 
davon abhängig! Anders kanns auch nicht sein, so stehts auch in der VHDL 
Implementierung.

Aus Erfahrung kann ich sagen, dass der Fehler (falls überhaupt einer 
vorliegt) meistens trivial ist. Auf die Tools zu schieben ist zwar 
heutzutage "in", aber man muss auch zugeben, dass bei so komplexen 
Sachen den Tools alles "vorgekaut" werden soll. Deshalb habe ich auch 
von Anfang an Dir geraten alles strukturierter zu schreiben.

Ich hoffe Du findest den Fehler und klärst uns alle auf :-) Sollte ich 
irgendwelche andere Ideen haben, melde ich mich. Ansonsten weiß ich 
nicht weiter. Viel Erfolg,

Kest

von Xenu (Gast)


Angehängte Dateien:

Lesenswert?

>Xenu? Ein klärender Beitrag von dir?

Wie gesagt, das ist ein Bug. Schreib am besten einen Fehlerbericht an 
Xilinx und sag denen auch, dass esi mit der alten ISE-Version noch 
funktioniert hat.

Ich hab den Code mal spaßeshalber mit Quartus für einen Cyclone II 
synthetisiert, siehe Bild.

von Kest (Gast)


Lesenswert?

Wieso ist das ein Bug?

Hast Du mal die RTL-Ansichten verglichen? Ich würde fast sagen, sie 
ähneln sich sehr. In der 9.2 Version ist das bloß zusammengepackt in 
einem BlockRAM und nicht in 2 aufgeteilt. Nur dir Größe kann ich mir 
nicht erklären.

Laut VHDL Beschreibung sind das keine zwei dual-Ports Rams. Wenn man 
genau hinschaut, dann ist das nur einer! Geschrieben wird nur ein Mal 
(entweder Lo oder Hi) und gelesen auch nur ein Mal (32 Bit zusammen).

Ich habe das Gefühl, dass ihr einfach alles so hintrimmen wollt, damit 
RTL-View so aussieht, wie ihr es haben wollt. Wenn das so ist, ist Deine 
(Xenu) Beschreibung der Enable-Signalen "richtiger", weil wahrscheinlich 
ISE das nicht optimieren kann.

Ich frage mal frech, wenn Simulation funktioniert, funktioniert auch die 
Synthese? Also die Hardware? (unabhängig davon, dass die Größe nicht 
erklärbar ist)




Grüße,

Kest

von Martin K. (mkohler)


Lesenswert?

Ach...

Gut, ich habe die ISE 9.2 RTL-Schematic Ausgabe ein wenig modifiziert 
(siehe Anhang).
- über Write_ADDR, Write_DATA und WEA wird das RAM beschrieben
- über Read_ADDR und READ_DATA wird das RAM gelesen

Nun sieht man, dass READ_DATA nicht nur von Read_ADDR (gelber Pfeil), 
sonder auch von Write_ADDR (pink Pfeil) abhängt.

Das stimmt definitiv nicht mit dem VHDL Code überein
1
    -- RAM Daten auslesen
2
    DB(15 downto 0)  <= RAM_L(conv_integer(AB(9 downto 2)));
3
    DB(31 downto 16) <= RAM_H(conv_integer(AB(9 downto 2)));
wo gilt:
DB => Read_DATA
AB => Read_ADDR

AA => Write_ADDR hat im Read_DATA Vektor nichts zu suchen.

Klarer kann und will ich meinen Punkt nicht mehr erläutern. Ich gehe 
nach wie vor von einem Fehler im Tool aus und warte auf Antwort des 
Xilinx FAE (welchen ich schon kontaktiert habe). Danke an Xenu für die 
Unterstützung.

Gruss, Martin

von Martin K. (mkohler)


Angehängte Dateien:

Lesenswert?

...und noch das Bild!

von Martin K. (mkohler)


Lesenswert?

Kest wrote:
> Ich habe das Gefühl, dass ihr einfach alles so hintrimmen wollt, damit
> RTL-View so aussieht, wie ihr es haben wollt. Wenn das so ist, ist Deine
> (Xenu) Beschreibung der Enable-Signalen "richtiger", weil wahrscheinlich
> ISE das nicht optimieren kann.
Absolut nicht. Ich will überhaupt nicht RTL trimmen. Hätte ich sonst ein 
möglichst generisches Konstrukt für das RAM gewählt?

> Ich frage mal frech, wenn Simulation funktioniert, funktioniert auch die
> Synthese? Also die Hardware? (unabhängig davon, dass die Größe nicht
> erklärbar ist)
Und ich antworte hoffentlich nicht allzu frech:
Die Simulation funktioniert, ja. Sie liefert mir auch die benötigten 
insgesamt 1kByte RAM. Das Schreiben und Herauslesen funktioniert in der 
Testbench tadellos.
Die Synthese/Hardware funktioniert eben NICHT. Und sie funktioniert 
genau so falsch wie es die 9.2 RTL-View zeigt.

Ich schreibe z.B. folgende Daten ins RAM, 16bit breit:
A: D:
0: 0000
1: 1111
2: 2222
3: 3333
4: 4444
5: 5555
6: 6666
7: 7777
8: 8888
9: 9999

Nach dem Schreibvorgang wird die Schreibadresse wieder auf 0 gestellt.
Während dem Auslesen bleibt die definitiv auf 0 (ablaufbedingt).

Ich lese dann folgende Daten aus dem RAM (32Bit breit)
0: 0000 0000
1: 0000 2222
2: 0000 4444
3: 0000 6666
4: 0000 8888

Man sieht, dass die höherwertigen 16Bit konstant sind und die auf 
Schreibseite Adresse 0 geschriebenen Daten liefern, unabhängig von der 
auf der Leseseite eingestellten Adresse.

Die RTL-View und die Realität stimmen überein, sind also "gleich 
falsch".

Gruss, Martin

von Joko (Gast)


Lesenswert?

Hi Allerseits,

  denke, es ist ein XST-Bug, aber....

   1) Precision RTL baut 2 BRAMs

  dies is noch kein Beweis, aber...

XST 9.2 hat wohl ein Problem, weil es feststellt, daß Du Ressourcen 
verschwendest: 1 BRAM kann 1024 x 16 Bit fassen (zumindest die aktuellen 
ARCHITEKTUREN9 - also passen da locker 2 x 256 Worte a 16 Bit rein.

XST-Gedanke: ich nehm 1 BRAM und verwende 1inen Port für RAM_L und einen 
Port für RAM_H.

Soweit toll - coole Lösung.

Problem: XST scheint zu "übersehen", daß die Leseadresse unabhängig von 
der Schreibadresse ist - und produziert Schrott.

--Schade: manchmal sind die Tools zu intelligent
Aber => DIE LEHRE:
1) Achte auf Deinen Coding-Style - mach es den Tools nicht zu schwer, 
bzw.
lauf auf "ausgetretenen Wegen" - exotische Codierung testet die Qualität 
der Tools, führt aber auch dazu, daß Du der erste biste, der den Bug 
bemerkt !!!!

2) überpüfe, ob Du die Addressierung nicht so abändern kannst, daß 
tatsächlich EIN BRAM ausreicht, um 'wertvolle' Ressourcen für andere 
Funktionen zu sparan..

Gruß
Joko

P.S.
   bitte poste die Antwort Deines FAEs - würde mich interessieren

von Martin K. (mkohler)


Lesenswert?

Joko wrote:
>    bitte poste die Antwort Deines FAEs - würde mich interessieren

Das werde ich tun.

Die Anordnung habe ich so gewählt, weil ich auf der Schreibseite mit 
16Bit daher komme und diese auf der Leseseite mit 32Bit auslesen will.

Mit den beiden separaten RAM kann ich die beiden 16Bit Vektoren bequem 
zusammensetzen ohne mich um High/Low 16Bit  Byte ... kümmern zu 
müssen.
In einem gewissen Sinne ist es wohl Bequemlichkeit.

Wie wäre denn dein Vorschlag, mein RAM zu beschreiben?
Momentan ist die Xenu-Variante implementiert und läuft auch.

Gruss, Martin

von Xenu (Gast)


Lesenswert?

@Kest:

Bei den Xilinx-Dual-Port-RAMs hast Du zwei Leseports und einen 
Schreibport. Allerdings nur zwei Adressen: einen zum Lesen, den anderen 
zum Lesen+Schreiben. Du kannst also bei einem BRAM nicht gleichzeitig 
beide Ports lesen und zusätzlich auch schreiben (ausser Schreibadresse = 
Leseadresse). Das ist aber genau das was Martin macht, und deshalb 
braucht er zwei BRAMs. Ob er die für seine Anwendung wirklich braucht 
sei mal dahingestellt, aber Deine Behauptung, dass der Code auch ein 
512x16-RAM darstellt ist falsch, weil es so ein Dreiadress-BRAM (noch) 
nicht gibt.

Und deshalb ist das ein Bug im Synthesizer, weil er - wie JoKo so schön 
beschrieben hat - etwas optimiert, was nicht zu optimieren ist.

von Kest (Gast)


Lesenswert?

Ich habe verstanden was Du meinst, doch Du irrst Dich.

Wenn ein DualPortRAM 32 Bit breit ist, dann kann man von einer Seite 
(mit 9 Bit) nur 16 Bit beschreiben und auf der Leseseite 32 Bit mit der 
8 Bit-Adresse auslesen.

Es ist somit nicht niotwendig 2 Ports zu schreiben, wozu auch -- Xilinx 
fasst beide zu 32 Bit zusammen und man hat einen 32 Bit Port, aber durch 
die Adressierung werden nur 16 Bit beschreiben.

Das ist keine Hexerei oder sowas, das habe ich zig Mal gemacht. Wenn die 
VHDL-Beschreibung strukturiert ist und man sich an Style-Guide hält 
(z.B. nur ein Write-Enable-Signal und nicht verschachtelte IF-Then), 
dann funktioniert alles so, wie gedacht.



Grüße,

Kest

von Martin K. (mkohler)


Lesenswert?

Update in dieser Sache:
Der FAE meinte, dass es wirlich nicht klar sei, ob das Problem wegen 
einem ISE Fehler oder schlechtem Coding Style auftaucht und hat mir 
empfohlen, bei Xilinx einen WebCase zu eröffnen.
Das hat jedoch noch nicht geklappt, weil die meinen Request vorerst mal 
abgelehnt haben.
Ich werde weiter berichten, wenn ich mehr weiss (und gehe bis auf 
weiteres immer noch von einem ISE Problem aus ;-) )

Gruss, Martin

von Martin K. (mkohler)


Lesenswert?

Update:
Der WebCase ist erstellt, bin gespannt auf die Analyse der Xilinx Gurus.

Martin

von Martin K. (mkohler)


Lesenswert?

Update:

Nach einigem Email-Verkehr mit dem Xilinx-Mitarbeiter habe ich heute 
folgende Nachricht erhalten:
"After running some further tests and after taking a closer look, you 
are correct, it does affect the functionality. When Synplify Pro is used 
for the synthesis, the design synthesizes correctly. I will file a 
Change Request against this bug."

Schönen Gruss an den User "Kest" ;-)

Gruss, Martin

von Rick Dangerus (Gast)


Lesenswert?

Danke.

Ich habe bei mir auch ein DPRAM im Design. Der ist genau so beschrieben, 
wie es im XST-Guide steht.

ISE 9.1 macht es richtig. ISE 9.2 will distributed RAM draus machen und 
der darf aber keine zwei Ports haben :(

Also: Während des Projektes nur ein Update machen, wenn man die alte 
Version noch in der Hinterhand hat!

Rick

von Kest (Gast)


Lesenswert?

@Martin Kohler (mkohler):

Danke für die Grüße! :-)

Was lernen wir also daraus?

a) Xilinx ist voller Bugs
b) hättest Du von Anfang an VHDL-DP-Ram anders beschrieben (ein Blockram 
pro Process, wie im XST-Guide steht), wäre es nicht passiert

Es war eigentlich auch zu erwarten, ich meine, nicht umsonst gibt es 
Tools, die besser mit solchen Sachen umgehen können (die kosten aber 
auch Geld). Na ja.

Grüße zurück aus Berlin,


Kest

von Martin K. (mkohler)


Lesenswert?

> Was lernen wir also daraus?
Mit XST weiterfahren und die Resultate weiterhin kritisch hinterfragen - 
auch wenn andere einem nicht glauben wollen, dass das Tool einen Fehler 
gemacht hat.
> a) Xilinx ist voller Bugs
Ja.
> b) hättest Du von Anfang an VHDL-DP-Ram anders beschrieben (ein Blockram
> pro Process, wie im XST-Guide steht), wäre es nicht passiert
Darum ging es nicht. XST hatte einen Fehler, was du bestritten hast.
> Es war eigentlich auch zu erwarten,
Was genau? dass es trotzdem ein Bug war? Ein klammheimlicher 
Meinungsumschwung also ;-)
> Tools, die besser mit solchen Sachen umgehen können (die kosten aber
> auch Geld). Na ja.
Ist bekannt.

Gruss, Martin

von Kest (Gast)


Lesenswert?

Mein Fehler war, dass ich RTL-View falsch interpretiert habe (nähmlich, 
dass man Read und Write-Ports untereinander vertauschen kann). Müsste 
ich selber so ein RTL-Diagramm zeichnen, würde es auch so aussehen, wie 
von XST (fehlerhaft) :-/

Zu der Sache, dass es Dir "niemand glauben wollte, dass XST einen Bug 
hat":

Du hast hier gepostet, weil Du ein Problem hattest. Das ist ja okay, 
aber Du kannst natürlich nicht erwarten, dass jetzt jeder Dir zustimmt 
und sagt, "ja, es ist ein Bug". Es ist mehr wichtiger, dass man Dir dann 
aufzeigt, dass es auch anders sein kann. Denn nur so kannst Du dann 
selber, wie Du schreibst, kritisch hinterfragen, ob das wirklich so ist.

Man stelle sich nur vor, wenn jemand das gleiche Design mit der gleichen 
Version von Xilinx XST bei sich synthetisiert hätte und es wäre das 
Richtige rausgekommen? :-o Dass es ein Bug ist, ist einfach zu sagen und 
mich befriedigt soetwas fast nie. Ich gehe Sachen gerne auf den Grund. 
Ansosten kann man große (FPGA) Designs nicht mache -- wer weiß, was 
später noch auftaucht.

Viel Erfolg,

Kest

von Martin K. (mkohler)


Lesenswert?

Kest wrote:
> Du hast hier gepostet, weil Du ein Problem hattest. Das ist ja okay,
> aber Du kannst natürlich nicht erwarten, dass jetzt jeder Dir zustimmt
> und sagt, "ja, es ist ein Bug".
So soll es sicher nicht sein. Nur warst du der einzige, der sich 
mehrfach dagegen aussprach, dass es ein Bug ist. Obwohl ich die Sachlage 
ja hinreichend dokumentiert hatte.
Erst die Nachricht von Xilinx hat den Meinungsumschwung bewirkt.

> Es ist mehr wichtiger, dass man Dir dann
> aufzeigt, dass es auch anders sein kann. Denn nur so kannst Du dann
> selber, wie Du schreibst, kritisch hinterfragen, ob das wirklich so ist.
Ack. Nur darf das Aufzeigen des anderen nicht das ursprüngliche Problem 
überdecken.

> Man stelle sich nur vor, wenn jemand das gleiche Design mit der gleichen
> Version von Xilinx XST bei sich synthetisiert hätte und es wäre das
> Richtige rausgekommen? :-o
> Dass es ein Bug ist, ist einfach zu sagen und
Hätte ich nachgehakt bei Xilinx wenn ich es mir einfach machen wollte? 
Nein! Sonst hätte ich gleich sofort den Xenu-Workaround benutzt.

> mich befriedigt soetwas fast nie. Ich gehe Sachen gerne auf den Grund.
> Ansosten kann man große (FPGA) Designs nicht mache -- wer weiß, was
> später noch auftaucht.
Ack.

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
Noch kein Account? Hier anmelden.