Forum: FPGA, VHDL & Co. HyperBus Ideen


von Gustl B. (-gb-)


Lesenswert?

Hallo,

ich habe auf meine Bastelplatine auch einen RAM mit HyperBus Interface 
gelötet. 
https://www.mouser.de/datasheet/2/198/66-67WVH8M8ALL-BLL-938852.pdf

Das habe ich getan weil der nur wenige FPGA IOs benötigt und doch recht 
groß und schnell ist.

Das ist jetzt der letzte Bausteion auf dem Board den ich in Betrieb 
nehme und dazu habe ich ein paar Fragen zwecks Herangehensweise:

Der Stein kann ziemlich viel, lineare Bursts, wrapped Bursts, aber immer 
Bursts, die Burstlänge ist einstellbar und wenn man nur einzelne 
Bytes/Adressen schreiben will muss man eben während der restlichen 
Adressen im Burst das Mask Bit RWDS setzen damit die Daten nicht 
geschrieben werden.

Aber vieles brauche ich auch nicht. Ich will eigentlich nur linear lesen 
und schreiben. Daten vom ADC in das RAM und dann wieder vom RAM um es 
über USB zu schaufeln. Ich denke daher an ein Interface zu meinem zu 
schreibenden Controller das gleich 32Byte breit ist, ein paar 
Handshaking Signale hat und noch die Startadresse des Bursts/Pageadresse 
übergibt.

Macht das Sinn oder vielleicht als generelle Frage:
Sollte man sehr breite Interfaces im FPGA vermeiden und die Daten lieber 
seriell übertragen? Als Alternative könnte ich auch einen kleinen 
Speicher einbauen. Dann wird immer gewartet bis der voll ist, dann wird 
das in den RAM geschrieben und wieder gewartet.

Und dann ist mir die Speicherorganisation noch etwas unklar.
Es gibt die Bits 44-16 das ist Row & Upper Column Address.
Dann gibt es noch die Bits 2-0, Lower Column Address.

Lower Column component of the target address: System word address bits 
A2-0 selecting the starting word within a half-page.

Und die Fußnoten:
1. A Row is a group of words relevant to the internal memory array 
structure and additional latency may be inserted by RWDS when crossing 
Row boundaries - this is device dependent behavior, refer to each 
HyperBus device data sheet for additional information. Also, the number 
of Rows may be used in the calculation of a distributed refresh interval 
for HyperRAM memory.
2. A Page is a 16-word (32-byte) length and aligned unit of device 
internal read or write access and additional latency may be inserted by 
RWDS when crossing Page boundaries - this is device dependent behavior, 
refer to each HyperBus device data sheet for additional information.
3. The Column address selects the burst transaction starting word 
location within a Row. The Column address is split into an upper and 
lower portion. The upper portion selects an 8-word (16-byte) Half-page 
and the lower portion selects the word within a Half-page where a read 
or write transaction burst starts.
4. The initial read access time starts when the Row and Upper Column 
(Half-page) address bits are captured by a slave interface. Continuous 
linear read burst is enabledby memory devices internally interleaving 
access to 16 byte half-pages.

Wenn also ein Burst 32 Bytes lang ist, dann sind das 16 Words. Da hätte 
ich jetzt 4 Bits erwartet als Adresse und nicht nur 3.

Ich würde gerne die LSBs immer auf 0000 lassen und so nur ganze Pages 
schreiben. Macht das Sinn?

Und noch eine Frage:
Habt ihr so einen Stein schon mal verwendet?

Zusatz:
Ja, ich weiß dass es IP dazu gibt. Diese will ich aber nicht verwenden 
weil ich das selber machen möchte und weil ich mir auch keinen Prozessor 
oder sonst wie AXI ins System holen möchte.

Wie machen das eigentlich richtige Speichercontroller mit dem 
Management? Ich stelle mir das schwierig vor wenn das System dem 
Controller nur Adressen und Daten zum Schreiben oder Lesen gibt. Ich 
stelle mir das so vor, dass der Controller Adressen und Daten zusammen 
in eine Cue packt und dort dann so umsortiert, dass er möglichst viele 
Daten zusammenhängend in Bursts lesen kann. Das hat dann aber das 
Problem, dass der Controller ja nicht ewig warten kann. Wenn also noch 
ein paar Adressen zu lesen sind die nicht zu einem Burst passen muss er 
das trotzdem tun irgendwann. Und dann ist noch das Problem, dass das 
System die Daten nicht in der Reihenfolge zurückbekommt in der es die 
Leseanfragen an den Controller gegeben hat. Vermutlich ist das eine 
ganze Wissenschaft für sich.

Danke!

von Tobias B. (Firma: www.elpra.de) (ttobsen) Benutzerseite


Lesenswert?

Gustl B. schrieb:
> Sollte man sehr breite Interfaces im FPGA vermeiden und die Daten lieber
> seriell übertragen? Als Alternative könnte ich auch einen kleinen
> Speicher einbauen. Dann wird immer gewartet bis der voll ist, dann wird
> das in den RAM geschrieben und wieder gewartet.

Noe, da kannst du ruhig zulangen. Wenn du Speicher Controller hast, dann 
hast du ziemlich oft breite Datenbusse (z.B. 320 bit sind da keine 
Seltenheit). Wenn das einigermassen vernuenftig gemacht ist, kommt man 
da auch auf ein paar 100 MHz Taktrate ohne Probleme zu bekommen.

Gustl B. schrieb:
> Wie machen das eigentlich richtige Speichercontroller mit dem
> Management? Ich stelle mir das schwierig vor wenn das System dem
> Controller nur Adressen und Daten zum Schreiben oder Lesen gibt. Ich
> stelle mir das so vor, dass der Controller Adressen und Daten zusammen
> in eine Cue packt und dort dann so umsortiert, dass er möglichst viele
> Daten zusammenhängend in Bursts lesen kann. Das hat dann aber das
> Problem, dass der Controller ja nicht ewig warten kann. Wenn also noch
> ein paar Adressen zu lesen sind die nicht zu einem Burst passen muss er
> das trotzdem tun irgendwann. Und dann ist noch das Problem, dass das
> System die Daten nicht in der Reihenfolge zurückbekommt in der es die
> Leseanfragen an den Controller gegeben hat. Vermutlich ist das eine
> ganze Wissenschaft für sich.

Gute Controller machen das auch. Kannst ja mal die Doku zum Xilinx MIG 
durchlesen um dir Inspiration zu holen.

: Bearbeitet durch User
von Gustl B. (-gb-)


Lesenswert?

OK, ja mein Problem ist eher zu entscheiden welche Features alles rein 
sollen und welche nicht. Wenn ich jetzt auch Zugriffe auf einzelne 
Adressen, unterstützen möchte, dann muss ich die anderen Bytes im Burst 
maskieren. Und dann muss ich entweder den Controller schlauer machen 
(was ich nicht will) oder das System muss dem Controller sagen können ob 
jetzt eine einzelne Adresse oder eine Page gelesen werden soll.

Edit:
Oder ist das vielleicht sogar üblich, dass das Betriebsystem sagt ob es 
jetzt eine Adresse oder eine Page lesen möchte?

Die andere Frage hat sich geklärt:
During linear transactions, accesses start at a selected location and 
continue in a sequential manner until the transaction is terminated when 
CS# returns High.
Das ist schön, ich kann mir also eine Länge aussuchen. Eher zwei Längen. 
Ich werde vermutlich das Lesen/Schreiben von einzelnen Words und von 
Bursts mit 16 Words(=Page) bauen.

Dann habe ich noch den hier gefunden:
https://github.com/gtjennings1/HyperBUS

Der hat

input  [31:0]   i_mem_wdata,
output [31:0]   o_mem_rdata,

32 Bit Daten.
Das macht an der Stelle vermutlich Sinn weil das für einen 32 Bit RiscV 
gedacht ist, aber das ist auch recht langsam. Das sind nur zwei Takte 
für die Datenübertragung, aber mindestens sechs Takte für Command und 
Warten. Naja ... war vermutlich ein Kompromiss weil man sonst eben einen 
schlaueren Controller bräuchte der Bursts kann und so.

: Bearbeitet durch User
von Vancouver (Gast)


Lesenswert?

Willst du dir das wirklich antun, einen eigenen Hyperbuscontroller zu 
schreiben? Da kann man eine ganze Menge Zeit drin versenken.

Wir haben diesen Controller verwendet : 
https://www.cypress.com/documentation/software-and-drivers/hyperbus-master-interface-controller-ip-intellectual-property
Der ist als Verilog-Code verfügbar und kostet nix, außer der 
Registrierung bei Cypress.

Im Nachfolgedesign werden wir diesen einsetzen:
https://github.com/pulp-platform/udma_hyperbus/tree/master/rtl
Das ist im Prinzip eine komplette Neuimplementierung in SystemVerilog 
und funktional dem Cypress-Core weitgehend identisch, aber vollständig 
OpenSource. Kann aber sein, dass der Richtung RISCV-Systeme optimiert 
ist.

von Gustl B. (-gb-)


Lesenswert?

Vancouver schrieb:
> Willst du dir das wirklich antun, einen eigenen Hyperbuscontroller zu
> schreiben? Da kann man eine ganze Menge Zeit drin versenken.

Ja schon, ist nur zu Lernzwecken.

Vancouver schrieb:
> SystemVerilog

Das kann ich (noch) nicht. Und kann daher nicht beurteilen ob der 
Controller Bursts unterstützt oder nur 32Bit Transaktionen. Ich brauche 
auf jeden Fall Bursts wenn ich 100 MBytes/s wegschreiben können will.

Der Cypress IP, welchen Anschluss hat der intern? Ist das AXI? Kann man 
den auch ohne CPU bedienen oder würde das extrem umständlich?

Ich habe mit dem Microblaze bisher nur sehr wenig gemacht. Zur 
Rechenleistung gibt es schon Angaben im Netz, aber wie sieht es beim 
Datendurchsatz aus? Schafft der es die 100 MBytes/s vom ADC zum RAM zu 
schaufeln?

von Duke Scarring (Gast)


Lesenswert?

Gustl B. schrieb:
> Ich habe mit dem Microblaze bisher nur sehr wenig gemacht. Zur
> Rechenleistung gibt es schon Angaben im Netz, aber wie sieht es beim
> Datendurchsatz aus? Schafft der es die 100 MBytes/s vom ADC zum RAM zu
> schaufeln?
Unwahrscheinlich. Aber sowas würde ich eine DMA-Engine, die direkt am 
Speichercontroller hängt machen lassen.

Duke

von Gustl B. (-gb-)


Lesenswert?

Duke Scarring schrieb:
> DMA-Engine

Genau sowas gibt es. Das ist auch fein wenn immer neue Daten nachkommen, 
aber ich habe da wieder so eine Angst die mich dann Dinge selbst 
schreiben lässt:

Z. B. kann man ich ja bei Xilinx einen FIFO generieren lassen als IP. 
Ich verwende den auch in manchen Projekten. Wie ist das wenn ich nur 
eine Bestimmte endliche Datenmenge übertragen möchte, z. B. 16 Bytes. 
Dann will ich am Ziel auch genau diese 16 Bytes haben - und zwar 
vollständig. Der FIFO hat aber die Einstellung, dass der das Empty Flag 
schon setzt wenn noch Daten drinnen sind.

Bei einem kontinuierlichen Datenstrom ist das OK, auch sonst könnte man 
die Daten die man haben will durch zusätzliche Daten "durchspülen".

Das sind so Dinge die ich bei einem AXI System aus der Hand gebe. Wenn 
ich so einem DMA IP dann eine Anzahl an Bytes gebe, landen die alle im 
RAM auch wenn das kein kontinuierlicher Datenstrom ist?

Ich müsste mir das mal zusammenklicken und gucken ... habe ich noch 
nicht gemacht.

von Dummbeutel (Gast)


Lesenswert?

Ist dieser Hyper-RAM so gestrickt wie ein Cellular-RAM?
Z.B. Micron MT45W4MW16BCGB?

von Gustl B. (-gb-)


Lesenswert?

Teilweise. Also ja, das ist ebenfalls pseudostatisch, aber du hast keine 
getrennten Daten und Adressleitungen. Sondern man hat nur 8 Leitungen 
(+Clock und so) und darüber wird zuerst in ein paar Takten ein Kommando 
übertragen, dann folgt eine Wartephase und dann werden da die Daten 
übertragen, DDR. Das ist also beim Burst schön schnell (333 MByte/s 
maximal), aber wenn nur einzelne Bytes an zufällige Adressen geschrieben 
werden sollen, dann bricht die Transferrate auch sehr stark ein. Das ist 
eben ein DRAM  und das Übertragen vom Kommando kostet bei 
Einzelzugriffen schon mehr Zeit als die Datenübertragung selbst. Bei mir 
ist das egal, ich will das nur als Samplespeicher verwenden. Da werden 
in großen Bursts 100 MByte/s hingeschrieben bis das RAM voll ist oder 
eben die Zahl der aufzunehmenden Samples, und dann wird langsam daraus 
gelesen und zum PC übertragen. Oben hatte ich ein PDF verlinkt, da kann 
man das Timing schön sehen. Das ist also eher ein serielles Interface 
wie SPI, nur eben OctaSPI mit DDR und Wartephasen und bidirektionalen 
Leitungen.

von Dummbeutel (Gast)


Lesenswert?

@ Gustl B.

TNX.

von Vancouver (Gast)


Lesenswert?

Gustl B. schrieb:
> Ja schon, ist nur zu Lernzwecken.

Das ist ein Argument, aber wie gesagt, der Aufwand ist nicht zu 
unterschätzen.

Gustl B. schrieb:
> Der Cypress IP, welchen Anschluss hat der intern? Ist das AXI?

Ja, AXI3 und AXI4.

Gustl B. schrieb:
> Kann man
> den auch ohne CPU bedienen oder würde das extrem umständlich?

Der Controller hat einige interne Register, die gesetzt werden müssen. 
Z.B, gibt es ein Setting, das ein Timing feingranular verschiebt, danmit 
es passt. Das muss sogar im laufenden Betrieb hin und wieder gemacht 
werden, wenn die Temperatur das Timing verändert. Du brauchst auf jeden 
Fall einen Controller, der das alles macht. Ob der Aufand ohne CPU zu 
groß ist, liegt in Deinem Ermessen. Wir betreiben den Controller an 
einem DMA mit einem RISCV.

Gustl B. schrieb:
> aber wie sieht es beim
> Datendurchsatz aus? Schafft der es die 100 MBytes/s vom ADC zum RAM zu
> schaufeln?

Ohne DMA wird das sportlich, zumindest, wenn der MB noch andere Dinge 
tun soll.

Gustl B. schrieb:
> Wenn
> ich so einem DMA IP dann eine Anzahl an Bytes gebe, landen die alle im
> RAM auch wenn das kein kontinuierlicher Datenstrom ist?

Aber natürlich. DMA hätte keinen Sinn, wenn die letzten Bytes irgendwo 
hängen bleiben. Ein DMA-Controller erzeugt erst einen Interrupt, wenn 
alle Daten übertragen wurden.

Gustl B. schrieb:
>> SystemVerilog
>
> Das kann ich (noch) nicht. Und kann daher nicht beurteilen ob der
> Controller Bursts unterstützt oder nur 32Bit Transaktionen.

Dazu müsste ich nochmal Kolleggah interviewen, aber soweit ich weiß, 
haben wir den Controller ausgewählt, weil der die HB-Spec vollständig 
umsetzt.
Wenn du VHDL kannst, sollte es aber kein allzu großes Problem sein, den 
SV-Code zumindest in groben Zügen zu verstehen. Learning by reading :-) 
Nach fast 15 Jahren VHDL habe ich SV ziemlich schnell gelernt, auch wenn 
ich noch längst nicht alle Details kenne.

von Gustl B. (-gb-)


Lesenswert?

Vancouver schrieb:
> unterschätzen

Kann ich, hab ich schon mal gemacht.

Vancouver schrieb:
> AXI3 und AXI4.

Habe ich ebenfalls schon mal gemacht, ohne CPU. Da habe ich den XADC und 
mal den UARTlite von Xilinx bedient. Quasi einen billigen AXI Master 
gespielt. War nicht irre schwer.

Vancouver schrieb:
> Der Controller hat einige interne Register, die gesetzt werden müssen.
> Z.B, gibt es ein Setting, das ein Timing feingranular verschiebt, danmit
> es passt.

Also dass ich im RAM vielleicht die Configregister beschreiben muss ist 
OK, aber das Timing nachträglich korrigieren und die Temperatur 
überwachen? Nein. Da gehe ich lieber mit dem Takt runter. Mir reichen ja 
100 MBytes/s. Bei 1,8 V kann das RAM 166 MHz, ich betreibe den Rest im 
FPGA großteils mit 100 MHz und wollte das auch mit dem RAM machen. Also 
200 MHz DDR. Das sollte entspannt funktionieren.

Vancouver schrieb:
> Aber natürlich. DMA hätte keinen Sinn, wenn die letzten Bytes irgendwo
> hängen bleiben. Ein DMA-Controller erzeugt erst einen Interrupt, wenn
> alle Daten übertragen wurden.

Danke!

Vancouver schrieb:
> Learning by reading :-)

So mache ich das auch oft, ob man wirklich alle Details kennen sollte 
weiß ich nicht. Ich komme auch ganz gut mit einem Teil aus VHDL zurecht. 
Aber man kann immer was dazulernen.

von Gustl B. (-gb-)


Angehängte Dateien:

Lesenswert?

So, ich laufe gerade in einige Fragen hinein:

Dieser HyperBus verlangt, dass bei der Übertragung vom FPGA zum RAM die 
Daten so anliegen, dass die Taktflanke mittig in den Daten liegt.
Das muss ich also beim Übertragen der 6 Bytes für das Command und beim 
Schreiben in das RAM einhalten.

Wenn ich aus dem RAM lese, dann treibt der RAM das RWDS Signal und legt 
die Daten passend dazu an, und zwar wieder so, dass die RWDS Flanken 
schön mittig in den Daten liegen.

Meine Fragen sind jetzt welche Hardwareblöcke ich verwenden sollte. 
Biesher habe ich jetzt den SelectIO Wizard verwendet, und ein 
bidirektionales DDR Interface erzeugt. Da kann ich aber die ausgegebenen 
Daten nicht gegenüber dem ausgegebenen Takt verzögern. Es kommt also 
sowas raus wie in Screenshot, da liegt die Flanke nicht mittig in den 
Daten.

Wäre es vernünftiger Datenausgabe, Dateneinlesen und Clock komplett 
getrennt zu machen, also nicht über einen SelectIP IP?
Z. B. einen IP oder so zum einlesen der DDR Daten mit RWDS und einen IP 
zur Datenausgabe und noch einen IP/ODDR zur Taktausgabe. Und noch einen 
ODDR zur Taktausgabe für die phasenverschobene Clock PSC.
Das Tristate würde ich dann in der Toplevel VHDL machen.

Dann möchte ich das schön einfach halten und "nur" die 100 MHz verwenden 
die synchron zum Rest des Systems sind. Ist das der richtige Weg, oder 
wäre es sinnvoll da 200 MHz verwenden damit ich die Daten bei 100 MHz um 
einen halben Takt verschoben ausgeben kann? Dann könnte ich auch den 
Takt quasi manuell ausgeben.

: Bearbeitet durch User
von Gustl B. (-gb-)


Lesenswert?

So, ODELAY gibt es in HR Bänken nicht ... und der Spartan hier hat nur 
HR Bänke. Naja, gut.

Ich könnte jetzt mit 4 Takten arbeiten:
1. Der 100 MHz Takt zu dem ich die Daten mit dem SelectIO IP als DDR 
ausgebe.
2. Ein um 90° verschobener 100 MHz Takt den ich dann differentiell als 
CK und CK# ausgebe.
3. Ein weiterer gegebüber 1. um 180° verschobener 100 MHz Takt den ich 
als PSCK und PSCK# ausgebe.
4. Beim Lesen treibt der RAM Stein das Signal RWDS, das ist dann also 
auch ein Takt mit dem ich die DDR Daten übernehme.

Würde man die Verschiebung von 2. und 3. mit Constraints lösen? Also 
dass 2. um 2.5 ns nach 1. oder nach den Daten anliegt und dass 3. noch 
mal 2.5 ns später ausgegeben wird?

von Gustl B. (-gb-)


Angehängte Dateien:

Lesenswert?

So, jetzt mit passenden Takten. Die kommen jetzt aber alle aus einem 
MMCM und werden je über ein OBUFDS ausgegeben.

von Tobias B. (Firma: www.elpra.de) (ttobsen) Benutzerseite


Lesenswert?

Hast du mal die Setup und Hold Zeiten als Constraints in deiner XDc 
angegeben? Jenachdem wie kritisch die sind, brauchst du da nicht von 
Hand an der Phase rumfummeln.

Wie klein/gross sind den Setup & Hold?

von Gustl B. (-gb-)


Lesenswert?

Tobias B. schrieb:
> Hast du mal die Setup und Hold Zeiten als Constraints in deiner XDc
> angegeben?

Bisher noch nicht.

Tobias B. schrieb:
> Jenachdem wie kritisch die sind, brauchst du da nicht von
> Hand an der Phase rumfummeln.

Ja, was wird denn dann durch Routingdelay verschoben? Der Takt nach 
hinten?

Tobias B. schrieb:
> Wie klein/gross sind den Setup & Hold?

Bei 100 MHz ist das jeweils 1 ns. Im Datenblatt steht center aligned 
drinnen, und daran wollte ich mich halten. Bei 100 MHz liegen die Daten 
maximal 5 ns an. Davon müssen sie 2 na stabil sein, also 1 ns vor der 
Taktflanke und 1 ns nach der Taktflanke. Ich finde das ist recht 
entspannt.

Selbst bei maximalem Takt von 166 MHz sind Setup und Hold nur 0,6 ns. Da 
ist also eine Periode 6 ns, eine halbe Periode also 3 ns die die Daten 
maximal anliegen könnten und davon genügen 1,2 ns um die Taktflanke 
herum.

von Gustl B. (-gb-)


Lesenswert?

So, da bin ich wieder ... meine Testbench macht schon den 
Schreibevorgang wie im Datenblatt, aber ob das wirklich passt und um 
auch aus dem RAM zu lesen brauche ich jetzt das RAM in der Simulation. 
Und das gibt es auch, aber es verwendet Dinge die mein Vivado nicht 
kennt:
1
LIBRARY IEEE;
2
    USE IEEE.std_logic_1164.ALL;
3
    USE IEEE.VITAL_timing.ALL;
4
    USE IEEE.VITAL_primitives.ALL;
5
    USE STD.textio.ALL;
6
7
LIBRARY FMF;
8
    USE FMF.gen_utils.all;
9
    USE FMF.conversions.all;

Tja was kann ich da machen? Wenn ich das nicht simulieren kann würde ich 
mir selber eine Testbench schreiben die RAM spielt. Und wenn das passt 
würde ich eben auf der Hardware testen.

In dem .zip hier https://www.cypress.com/verilog/s27kl0641-verilog ist 
auch das VHDL Modell und eine Testbench drinnen.

von Markus F. (mfro)


Lesenswert?

Modelsim müsste die notwendigen VITAL2000-Libraries mitbringen.

Den Rest gibt's da, wo Du das model her hast.

[edit: nö, da: https://freemodelfoundry.com/packages.php]

: Bearbeitet durch User
von Tobias B. (Firma: www.elpra.de) (ttobsen) Benutzerseite


Lesenswert?

Markus F. schrieb:
> Modelsim müsste die notwendigen VITAL2000-Libraries mitbringen.

GHDL auch. Evtl. muss man da aber mit dem -frelaxed-rules Switch 
arbeiten.

von Gustl B. (-gb-)


Lesenswert?

OK, danke. Für dieses Projekt würde ich schon gerne bei dem Vivado 
Simulator bleiben.

Wie ist das "draußen", welcher Simulator hat da grob welche 
Marktdurchdringung?

von Tobias B. (Firma: www.elpra.de) (ttobsen) Benutzerseite


Lesenswert?

Gustl B. schrieb:
> Wie ist das "draußen", welcher Simulator hat da grob welche
> Marktdurchdringung?

Das kann man so pauschal nicht sagen. Haengt stark vom Projekt, der 
Sicherheitsklasse, den Prozessen und letztendlich auch vom Budget ab.

von Markus F. (mfro)


Lesenswert?

Gustl B. schrieb:
> OK, danke. Für dieses Projekt würde ich schon gerne bei dem Vivado
> Simulator bleiben.

Hat keiner gesagt, dass Du den Simulator wechseln sollst...

von Gustl B. (-gb-)


Lesenswert?

@ Tobias B.: Es gibt also keinen "Industriestandard"?

Nun, die Tipps hier haben waren Modelsim und GHDL, das klingt für mich 
danach, dass ich nicht den Vivado Simulator nutzen sollte.

von Markus F. (mfro)


Lesenswert?

Gustl B. schrieb:
> Nun, die Tipps hier haben waren Modelsim und GHDL, das klingt für mich
> danach, dass ich nicht den Vivado Simulator nutzen sollte.

Beide genannten Pakete enthalten die VITAL2000 Quellen

von Gustl B. (-gb-)


Lesenswert?

OK, ich habe noch nicht wirklich verstanden was die VITAL2000 Teile 
sind. Ist das sowas wie das IEEE das ich in einen Ordner kopieren muss 
damit es vom Simulator gefunden werden kann?

von Tobias B. (Firma: www.elpra.de) (ttobsen) Benutzerseite


Lesenswert?

Gustl B. schrieb:
> @ Tobias B.: Es gibt also keinen "Industriestandard"?
>
> Nun, die Tipps hier haben waren Modelsim und GHDL, das klingt für mich
> danach, dass ich nicht den Vivado Simulator nutzen sollte.

Jeder nutzt das womit er glaubt seine Ziele zu den geringsten Kosten zu 
erreichen. Ich kenne keinen Standard oder Norm welche vorschreibt dass 
dieser oder jener Simulator verwendet werden muss.

Die Questa Produktfamilie von Mentor hat zum Beispiel eine ISO 26262 
Zertifizierung, siehe z.B.: 
https://www.mentor.com/company/news/mentor-achieves-iso-26262-cert-questa-product-tool-qualification-report

D.h. aber noch lange nicht, dass ich nur mit ISO 26262 zertifizierten 
Tools entsprechend entwickeln darf. (Falls das falsch sein sollte, bitte 
jemand korrigieren, ich komme aus der Medizin und hab mit Automotive 
nicht viel am Hut.)

Eine Uebersicht findest du hier 
https://en.wikipedia.org/wiki/List_of_HDL_simulators inkl. einer 
MArkierung der "Big 3". Wobei auch die Big 3 relativ sind, stark 
Branchen abhaengig und nicht wirklich auf empirischen Daten beruhend 
(dazu kommt noch dass diese auch den ASIC Markt beherrschen). Was ma 
jedoch ziemlich sicher sagen kann: Die Big 3 sind auch die Top 3 unter 
den Preisen. ;-)

: Bearbeitet durch User
von Gustl B. (-gb-)


Lesenswert?

Danke! Ich habe mir aber jetzt selber einen RAM Baustein geschrieben für 
die Simulation. Funktioniert auch schon alles wunderbar in der 
Simulation.

Ich habe mich jetzt entschieden, dass ich einzelne 2 Byte (das ist ein 
Takt und 1 Word) Transfers und lineare Bursts mit 64 Bytes unterstütze. 
Beides lesend und schreibend.

Tja warum 64 Bytes? Nun wenn ich die Config Register im RAM nicht 
anfasse, dann hat das 6 Takte Latenz und immer die zweifache Latenz 
(RWDS = '1'). Wenn ich einen 32 Byte Burst mache, dann brauche ich dafür 
1+2+2*6+16+1+1 = 33 Takte, Damit liege ich bei 100 MHz unter den 
angepeilten 100 MBytes/s. In den Config Registern könnte ich die Latenz 
auf 4 Takte runtersetzen bei 100 MHz, aber ... wenn ich das nicht muss 
lass ich das.

Bei 64 Byte Bursts brauche ich 1+2+2*6+32+1+1 = 49 Takte, also 490 ns 
bei 100 MHz. Das macht dann 64Bytes*1s/490ns macht 130,6 MBytes in einer 
Sekunde.

Aber: Das sind jetzt echt viele Bits/Leitungen im FPGA. 512 hin und 512 
zurück ... mal gucken ob das auch auf Hardware funktioniert.

von Gustl B. (-gb-)


Lesenswert?

So, ... es baut nicht.

[Route 35-54] Net: HyperRAM_RWDS_IOBUF_inst/O is not completely routed.
[Route 35-7] Design has 1 unroutable pin, potentially caused by 
placement issues.

Ja was ist das? Nun, beim HyperBus ist es so, dass es ein RWDS Signal 
gibt.
Wenn man in den RAM schreibt, dann kann man mit dem RWDS die Daten 
maskieren.
Wenn man aus dem RAM liest, dann ist das RWDS der Takt mit dem man die 
Daten vom RAM eintaktet.

Ich habe mir also mit dem SelectIO IP das bauen lassen:
1
component HyperBus_IN generic(
2
  SYS_W: integer := 8;
3
  DEV_W: integer := 16);
4
  port(
5
  data_in_from_pins : in  std_logic_vector(SYS_W-1 downto 0);
6
  data_in_to_device : out std_logic_vector(DEV_W-1 downto 0);
7
  delay_locked      : out std_logic; 
8
  ref_clock         : in  std_logic; 
9
  clk_in            : in  std_logic; 
10
  clk_out           : out std_logic;
11
  io_reset          : in  std_logic);
12
end component;

Und verwende das so:
1
HB_IN: HyperBus_IN port map( 
2
  data_in_from_pins => DQ_IN,
3
  data_in_to_device => RX_Data,
4
  delay_locked => open,                      
5
  ref_clock => MMCMCLK200,                       
6
  clk_in => RWDS_IN,                           
7
  clk_out => DQ_IN_CLK,
8
  io_reset => '0');

RWDS ist natürlich ein inout, also habe ich den als Tristate 
beschrieben:
1
RWDS <= RWDS_OUT when RWDS_tristate = '0' else 'Z';
2
RWDS_IN <= RWDS;

Weil ich nicht weiß wie ich das korrekt löse, wäre mein nächster Ansatz, 
den RWDS nicht als inout, sondern nur noch als in zu beschreiben, aber 
mit Pulldown. Ja, dann kann ich keine Bits maskieren, aber das habe ich 
sowieso nicht vor.

Gibt es eine bessere Lösung?

von Gustl B. (-gb-)


Lesenswert?

Ja "Fehler" gefunden. Und zwar habe ich RWDS_IN nicht nur an den IP 
Block gegeben, sondern auch zusätzlich noch an einer Stelle verwendet. 
Aber das muss ich ja auch machen, denn am Anfang der Transaktion ist 
RWDS noch keine Clock oder Maskierung, sondern zeigt an ob das RAM 
einfache oder doppelte Latenz für die Daten benötigt.

Ich habe jetzt RWDS nur als in mit Pulldown beschrieben und das baut.

Edit:
Jetzt wieder als inout, aber bei dem IP habe ich nicht external sondern 
internal Clock angegeben und verwende dort das RWDS_IN.

: Bearbeitet durch User
von Christoph Z. (christophz)


Lesenswert?

Tobias B. schrieb:
> Jeder nutzt das womit er glaubt seine Ziele zu den geringsten Kosten zu
> erreichen.

"Wir sparen, egal was es kostet" ist ein beliebtes Sprichwort hier unter 
den Ingenieuren.

Nichts kaufen (Softwaretools, Schulungen, Bücher, Busanalyzer, 
Messgeräte, Build-Server, Rapid-Prototyping Systeme...), dafür mehr 
Personenstunden ist bei Schweizerlöhnen vielleicht nicht die Variante 
mit den geringsten Kosten...

von Tobias B. (Firma: www.elpra.de) (ttobsen) Benutzerseite


Lesenswert?

Ja, das ist nicht optimal. Wahrschenlich fallen entsprechende Firmen bei 
noch mehr Punkten im Joel Test durch. ;-)

Aber zum Glueck arbeiten nicht alle so.

von Christoph Z. (christophz)


Lesenswert?

Tobias B. schrieb:
> Ja, das ist nicht optimal. Wahrschenlich fallen entsprechende Firmen bei
> noch mehr Punkten im Joel Test durch. ;-)

In einer früheren Firma hatte ich den Joel Test mal in der Kaffeeecke 
aufgehängt (Die war gerade von 3 auf 4 Punkte raufgeklettert durch 
einführen von Versionskontrolle). Leider keine Reaktion...

Was auch Spass macht, ist den Joel Test VOR einem Bewerbungsgespräch zur 
Beantwortung einzusenden.

von Gustl B. (-gb-)


Lesenswert?

1. Do you use source control?
 2. Can you make a build in one step?
 3. Do you make daily builds?
 4. Do you have a bug database?
 5. Do you fix bugs before writing new code?
 6. Do you have an up-to-date schedule?
 7. Do you have a spec?
 8. Do programmers have quiet working conditions?
 9. Do you use the best tools money can buy?
10. Do you have testers?
11. Do new candidates write code during their interview?
12. Do you do hallway usability testing?

Bei 2.: Was ist denn überhaupt ein "build"? Man kann immer den letzten 
Schritt einer langen vielschritten Kette als den "build" definieren und 
der läuft dann auch in einem Schritt. Oder ist das Starten eines Skripts 
ein Schritt?

Bei 3.: Was für ein Blödsinn, es reicht neu zu bauen wenn man auch was 
am Code geändert hat.

Bei 5.: Einige Bugfixes SIND neuer Code.

Bei 6.: Es gibt nichts was immer aktuell ist. Die Frage ist wie schnell 
es aktualisiert wird.

Bei 9.: Total sinnlos weil das oft eine Abwägung ist. Ja, eine kleine 
Firma könnte sich das weltbeste Tool kaufen dass dann noch ein klein 
wenig besser ist als das was sie derzeit nutzen, aber danach ist die 
Firma eben pleite. Und wieso überhaupt kaufen? Da zählen also Clang und 
GCC schon mal nicht zu Tools die verwendet werden dürfen.

Ja, sind gute Punkte dabei, aber wirkt wenig durchdacht.

Edit:
Mit wenig durchdacht meine ich vor allem die Formulierung. Bei 5. z. B. 
hätte man schreiben können und auch sollen:

5. Do you fix bugs before implementing new features.

: Bearbeitet durch User
von Tobias B. (Firma: www.elpra.de) (ttobsen) Benutzerseite


Lesenswert?

Christoph Z. schrieb:
> In einer früheren Firma hatte ich den Joel Test mal in der Kaffeeecke
> aufgehängt (Die war gerade von 3 auf 4 Punkte raufgeklettert durch
> einführen von Versionskontrolle). Leider keine Reaktion...

Dann hilft nur das Weite zu suchen. Nix ist schlimmer als eine Firma die 
ihre Probleme kennt, aber egal sind.

Christoph Z. schrieb:
> Was auch Spass macht, ist den Joel Test VOR einem Bewerbungsgespräch zur
> Beantwortung einzusenden.

Das haette ich mich damals nach der Uni nicht getraut und jetzt wo ich 
selbststaendig bin gibts keine Gelegenheit mehr. Aber den Tipp geb ich 
auf jedenfall weiter! :-)

@Gustl B.

Was der Joel Test beschreibt sind CI Prozesse in einfachen Fragen, diese 
sollte man als Experte nicht allzu woertlich nehmen, wir verstehen aber 
deren Kern sehr wohl. Da du noch sehr weit davon entfernt bist das zu 
verstehen, solltest du eine Bewertung des Joel Tests eher vermeiden. Das 
wuerde man dir als Mangel von Expertise auslegen und eher peinlich 
enden.

Was man evtl. schon anmerken kann ist, dass der Test knapp 20 Jahre alt 
ist, und seiner damaligen Zeit extrem vorraus war. Heute wuerde man den 
Test vll. ein bisschen zeitgemaesser machen, was den natuerlich eher 
strenger macht.

Kleiner Edit:

Hier 
https://www.joelonsoftware.com/2000/08/09/the-joel-test-12-steps-to-better-code/ 
sidn auch die Anmerkungen vom Autor selbst. An sich ist die ganze Seite 
sehr interessant und mit vielen inspirierenden Geschichten.

: Bearbeitet durch User
von Gustl B. (-gb-)


Lesenswert?

Natürlich verstehe ich den Hintergrund der Fragen, aber ich finde Fragen 
sinnfrei die entweder schlecht gestellt sind oder nicht zu ernst 
genommen werden sollen.

Was ist das eigentlich ausser Kompexitätsmanagement? Das läuft schon 
lange so, dass die Komplexität immer weiter wächst und statt dass man 
dann auf den UNIX Ansatz geht versucht man die Komplexität in den Griff 
zu bekommen indem man aussen noch was dranbaut. Das macht dann jeder so 
und plötzlich ist es "Industriestandard". Nur weil eine Mehrheit etwas 
so macht bedeutet das nicht, dass es gut ist.
Man kann sich mal gut angucken wie die Größe von quasi allem gestiegen 
ist. Irre fette Websites (https://player.vimeo.com/video/147806338 ), 
fette "Apps", ... und was kann es? Nicht wirklich mehr als vor 20 Jahren 
(2004 hatte ich ein Smartphone MPX200 mit Windows, Office, Browser, 
Spielen, Paint, Explorer, Outlook, Telefon/SMS und Musikplayer - in 32 
MByte Flash). Aber weil es jetzt so fett ist ist es schlechter wartbar. 
Statt das zu beheben, also das Problem mal an der Wurzel zu packen hat 
man oben noch ein wenig Komplexität draufgeworfen um die Komplexität 
drunter besser verwalten zu können.
Und wenn das dann so irre komplex ist, dass das System nurnoch auf genau 
dem System läuft auf dem es gebaut wurde dann ... packt man das einfach 
in eine VM/Qube/Cabinet/Container und liefert es einfach komplett aus 
(-:

Tolle Welt, aber nicht das was ich will. Sollte ich je nach einem Job in 
der Wirtschaft suchen dann ganz bestimmt nicht als 
Komplexitätsverwalter.

: Bearbeitet durch User
von Christoph Z. (christophz)


Lesenswert?

Gustl B. schrieb:
> Bei 2.: Was ist denn überhaupt ein "build"? Man kann immer den letzten
> Schritt einer langen vielschritten Kette als den "build" definieren und
> der läuft dann auch in einem Schritt. Oder ist das Starten eines Skripts
> ein Schritt?
1
git clone
2
make all

Mehr soll nicht nötig sein (natürlich sind andere build Systeme erlaubt)

Also das Gegenteil von (alles schon durchgemacht, nicht gerade alles so 
auf einmal):

1 Code vom Server kopieren (weil keine Versionskontrolle)
2 Projekt in IDE erstellen oder alle Pfade korrigieren (weil IDE zu doof 
und absolute Pfade benutzt)
3 Projekt Einstellungen setzen gemäss README (oder Word Dokument...)
4 Alle nötigen Schritte in der IDE/mehreren Tools ausführen bis eine 
Datei da ist, die man aufs Target laden kann (oder Windows Installer, 
Debian Packet, zip Datei mit Gerber Daten,...)
5 Programmiersoftware starten und gemäss Word Dokument alles richtig 
anklicken
6 Nach Hause gehen, weil der Arbeitstag schon vorbei ist.

Punkt 4 ist z. B. mit Vivado und Vivado SDK besonders lustig für Leute 
die das nur alle paar Wochen machen. Die verlieren bei uns jedesmal ein 
paar Stunden bis es wieder klappt.

Gustl B. schrieb:
> Bei 9.: Total sinnlos weil das oft eine Abwägung ist. Ja, eine kleine
> Firma könnte sich das weltbeste Tool kaufen dass dann noch ein klein
> wenig besser ist als das was sie derzeit nutzen, aber danach ist die
> Firma eben pleite. Und wieso überhaupt kaufen? Da zählen also Clang und
> GCC schon mal nicht zu Tools die verwendet werden dürfen.

Punkt 9 wird immer gerne kontrovers diskutiert. Ist auch provokativ 
formuliert, wohl bewusst.

"A fool with a tool is still a fool", freie Software ist nicht Gratis. 
Bücher, Schulungen, Support mit kurzen Reaktionszeiten kosten oder die 
Firma zahlt mehr Einarbeitungszeit. Ist eine Abwägung.


Ach ja, aktuelle Firma läuft bei 5 Punkten...

: Bearbeitet durch User
von Tobias B. (Firma: www.elpra.de) (ttobsen) Benutzerseite


Lesenswert?

Christoph Z. schrieb:
> Punkt 9 wird immer gerne kontrovers diskutiert. Ist auch provokativ
> formuliert, wohl bewusst.
>
> "A fool with a tool is still a fool", freie Software ist nicht Gratis.
> Bücher, Schulungen, Support mit kurzen Reaktionszeiten kosten oder die
> Firma zahlt mehr Einarbeitungszeit. Ist eine Abwägung.

Ich denke der Punkt war Anno 2000 schon noch korrekt. Heutzutage muesste 
es wohl eher heissen:

Do you use the best tools available?

Wobei im FPGA Bereich es weiterhin keine Alternative zu den wirklich 
teuren Flagschiffen gibt. Ich kenne z.B. kein Tool dass mir z.B. 
Functional Coverage und Code Coverage (soviel Line als auch Branch 
Coverage) bietet. Und da mittlerweile die Designs riesig sind, besteht 
nicht nur Bedarf an Functional sondern auch an Formal Verification um 
die Testzeiten endlich zu halten.

Wenn ich mir da z.B. anschaue was Mentor mit Questa Prime bietet, dann 
finde ich da nicht ansatzweise in der freien Software Gemeinde etwas was 
da ran kommt. Anderseits kann man mit GHDL in nemm Docker Container und 
z.B. noch mit VUnit schon richtig viel erreichen. Ist halt alles eine 
Frage der Anforderungen.

von Gustl B. (-gb-)


Lesenswert?

Tobias B. schrieb:
> Und da mittlerweile die Designs riesig sind, ...[]

Für mich als Laie sieht das teilweise sehr so aus wie in der 
Softwarebranche. Es soll möglichst schnell ein Produkt entstehen und 
dann baut man das mit Methoden die genau das versprechen. Dabei ist 
völlig egal ob das dann noch wartbar ist oder welche Abhängigkeiten von 
sonstwo man sich ins Haus holt. Und weil man das dann so gemacht hat 
braucht man auch mächtigere Werkzeuge die einem helfen irgendwie den 
Überblick zu behalten.

Ja, ist schön, dass man heutzutage so entwickeln kann, aber das ist dann 
nicht unbedingt robust. Bei FPGAs noch eher, da kann man immer das 
verwenden was man schon hat (ausser die Lizenz einer Mietsoftware läuft 
aus), aber im Webbereich wo gnadenlos externe Dinge eingebunden werden 
funktioniert das auch nur so lange wie diese auch vorhanden sind. 
Leftpad hätte eigentlich mal ein Umdenken lostreten können, hat es aber 
nicht. Weil es den Kunden/Enduser nicht interessiert. Und Firmen die ein 
Produkt verkaufen interessiert es im Consumerbereich auch immer weniger 
ob das lange beim Kunden funktioniert. Die Halbwärtszeit von Fernsehern 
z. B. ist krass gesunken und andere Geräte und auch Software "Apps" 
haben von hause aus oft nur eine kurze Lebenszeit. Und dann kann man ja 
heute fast überall nachpatchen. Wird ein Bug bekannt der kritisch ist 
für den Verdienst der Firma, dann behebt man den nachträglich. Da kann 
man schön abwägen ob es sich überhaupt rechnet einen Bug zu patchen oder 
ob man dem Kunden lieber ein neues Produkt verkauft oder einem die 
Kunden einfach egal sind.

Aber alles egal, jetzt gibt es Essen.

von Gustl B. (-gb-)


Lesenswert?

Hm, nun, der HyperRAM will nicht. Aus purer Dummheit habe ich mir aber 
die Debuggingmöglichkeiten etwas stark eingeschränkt. Ich habe den RAM 
IC direkt neben das FPGA gesetzt und komme so nur an manche Signale - an 
die, die durch ein Via geführt werden. Die kann ich schön angucken denn 
der dünne Fädeldraht passt ziemlich perfekt in ein Via. Sehen kann ich 
so RWDS, CK, PSCK, und ein paar der Bits. #Reset und #CS kann ich nicht 
angucken.

So, jedenfalls sehen CK und PSCK und die Daten (ich gucke mir DQ(0) an) 
gut aus vom Timing her. Allerdings hapert es beim Lesen, da bekomme ich 
einfach keine Daten. Für mich sieht das bisher nach einem Problem mit 
RWDS aus. Wenn ich das im FPGA auf 'Z' lege, dann bekommt es einen High 
Pegel - aber nie einen Low Pegel. Und zwar auch wenn ich im .xdc einen 
Pulldown für den Pin einbauen. Das sieht also so aus als würde der RAM 
RWDS immer treiben?! So recht kann ich das nicht glauben und dem Vivado 
vertraue ich auch nicht mehr. Normalerweise kann man ja die Simulation 
und so neu starten in der GUI und das verwendet dann die aktuellen 
Quellcode Dateien. Aber das ist leider nicht immer der Fall. Manchmal 
musste ich Vivado schließen, händisch die generierten Dateien löschen 
und dann Vivado neu starten. Dann wurde alles neu gebaut und die 
Simulation war wieder aktuell. Seltsam.

Daher die Frage:
Wenn ich einen Pin wie RWDS als Tristate mache UND da noch einen Pullup 
hinhänge, wo hängt der Pullup?
Hängt der Pullup zwischen Pad und Tristate oder hängt der Pullup am 
Ausgangstreiber, also zwischen FPGA Logik und Tristate?

Zusatzfrage 1:
Ich schaffe das nicht 4 Oszi Tastköpfe mit Massefeder gleichzeitig zu 
halten. Gibt es dafür eine elegante Lösung?

Zusatzfrage 2:
Ich gebe die Daten DQ mit den Takten CK/#CK und PSCK/#PSCK aus. Der 
Xilinx IP kann Clock forwarding. Das würde ich gerne nutzen und gleich 
eine differentielle Clock ausgeben. Aber welchen IO-Standard sollte ich 
da auswählen um den korrekten vollen 1,8 V Pegel zu bekommen?

Vielen Dank!

von Duke Scarring (Gast)


Angehängte Dateien:

Lesenswert?

Gustl B. schrieb:
> Ich schaffe das nicht 4 Oszi Tastköpfe mit Massefeder gleichzeitig zu
> halten. Gibt es dafür eine elegante Lösung?
Ich auch nicht ;-)

In ganz teuer:
https://www.packetmicro.com/Products/positioners-manipulator.html

In nur teuer:
http://www.pmk.de/de/products/3d_positionierer

In übertuert:
https://www.conrad.de/de/p/sks-hirschmann-tko-pos-2-positionierer-tko-pos-2-gruen-129043.html

In günstig, siehe Bild...

Duke

von Christoph Z. (christophz)


Lesenswert?

Duke Scarring schrieb:
> In günstig, siehe Bild...

Ja, so etwas (oder PMK 2-Fuss) sollte jeder in der Nähe haben.

PMK hat noch mehr nette Sachen, SKID, modulares System um Sonden und 
Leiterplatten beim Testen zusammen zu halten: http://www.pmk.de/de/skid

Zu teuer für zu Hause aber in einer Firma kann sich das schon rentieren.

Ein anderer Ansatz ist, sich bei den Chemikern mit Stativmaterial 
einzudecken, da kann man sich dann beliebig komplizierte Messsetups 
zusammenschrauben. Und das Chemikermaterial ist viel günstiger als das 
überteuerte Messgerätezubehör.

Ich habe keine Verbindung mit dieser Firma, einfach der erstbeste Link 
aus der Suchmaschine:
http://www.laborhandel24.de/allgemeiner-laborbedarf/stativmaterial.html?p=1

Es gibt auch Klammern mit Schwanenhals, die sind dann wieder eher teuer:
http://www.laborhandel24.de/allgemeiner-laborbedarf/stativmaterial/b08309658-de

von Gustl B. (-gb-)


Lesenswert?

OK, ja der Tipp mit den Stativen ist schon sinnvoll, sowas habe ich 
hier. Aber das braucht dann doch recht viel Platz und ich muss die 
Platine fixieren. Gibt es günstige Lötlösungen?
Vor einiger Zeit habe ich mal einen Oszi Tastkopf zerlegt. Da war nicht 
viel drinnen, drei Widerstände und ein Kondensator. Das könnte man doch 
auch in sehr klein und leicht bauen. Dann hinten ein dünnes Koax dran 
oder noch besser eine Buchse für SMA/UF.L und vorne zwei dünne drähte 
die ich direkt auf die Platine löten kann.
Ich habe mir das gebaut, aber eben nur mit billigen Tastköpfen. Die 
teureren mit 300 MHz Bandbreite will ich ungerne schlachten.
Gibt es sowas vielleicht schon fertig zu kaufen?

von Christoph Z. (christophz)


Lesenswert?

Ja, kann man kaufen. Die Listenpreise willst du eigentlich gar nicht 
wissen :-)

Bei schnellen (> 1 GHz) Aktiv-/Differenzproben von Keysight werden 
Einlötanschlüsse gleich mitgeliefert.

Das sieht z. B. so aus (Preis ist nur für den Adapter, ohne 
Vorverstärker): 
https://www.ebay.com/itm/Agilent-N5381A-InfiniiMax-II-12-GHz-differential-solder-in-probe-head/283427132692

: Bearbeitet durch User
von Gustl B. (-gb-)


Angehängte Dateien:

Lesenswert?

Genau sowas suche ich. Nur eben reichen bis so grob 300 MHz. Aber egal, 
ich habe jetzt die Platine mit Klebemand auf einer Platte befestigt, die 
Tastköpfe drauf gelegt und ebenfalls festgeklebt und die Signale über 
sehr kurzen Draht angelötet.

Im Anhang sind jetzt ein paar Bildchen, die zeigen wie folgt:
- Gelb: RWDS
- Cyan: CK
- Magenta: PSC
- Blau: DQ(0)

Hyper_LSB_XXX zeigen, wo die Bits beim Kommanto sitzen. Man kann sehen, 
dass die zur jeweiligen Flanke anliegen.
Hyper_Write zeigt einen Schreibvorgang an die Adresse 9. Geschrieben 
wird ein Wort.

Saltsam ist, dass der RAM IC scheinbar immer RWDS treibt. Beim Schreiben 
geht das nicht ganz runter, da treibt der FPGA und vermutlich der RAM IC 
das Signal obwohl beim Schreiben nach der Command Phase nurnoch der 
Master RWDS treiben darf.
Dann habe ich noch nicht verstanden wozu ich PSC brauche. Ja, 
anscheinend braucht das der RAM IC, aber wann genau? Laut Datenblatt 
kann ich das beim Schreiben auch statisch high oder low setzten. Aber 
beim Lesen brauche ich das wohl zwingend?! und muss da einen Takt mehr 
ausgeben als ich lesen will?! Im Timingdiagramm 
https://www.mouser.de/datasheet/2/198/66-67WVH8M8ALL-BLL-938852.pdf 
Seite 43 werden 4 Bytes gelesen (2 Takte mehr auf CK und zwei Takte auf 
RWDS) aber 6 Flanken über PSC ausgegeben.

Ja und dann ist noch minimal unklar wie viele Takte ich überhaupt warten 
muss als Latency. Default besitzt der RAM IC immer doppelte Latenz und 
die Latenz ist auf 6 Takte eingestellt (Config Register 0, Seite 20).
Das bedeutet, dass ich am Anfang zwei Takte von CK ausgebe und danach 
die doppelte Latenz von 6 Takten, also 12 Takte habe bis ich tatsächlich 
schreiben oder lesen darf.
Nach 14 Takten beginnt dann also der Burst.
In den Screenshots will ich nur ein Wort übertragen, also einen Takt. 
Dann müsste das stimmen mit den insgesammt 15 Takten.

von Gustl B. (-gb-)


Lesenswert?

Und das kann ich mir nicht erklären:

Ich habe RWDS als inout.

Daran hängt ein Tristate.

RWDS <= RWDS_OUT when RWDS_tristate = '0' else 'Z';
RWDS_IN <= RWDS;

Und jetzt kann ich aber (warum auch immer) problemlos RWDS_IN im FPGA in 
den Takteingang des DDR IPs geben und gleichzeitig noch in eine 
Bedingung schreiben (if RWDS_IN = '1' then ...).
Und das obwohl ich für den Takteingang des IPs external Clock gewählt 
habe.

Jetzt versuche ich den RWDS statt inout nur auf in umzubauen und einen 
Pulldown im XDC einzubauen.

Also Tristate raus, und zwar nur die obere Zeile entfernt:
RWDS_IN <= RWDS;

RWDS_IN geht weiterhin an den Takteingang des IPs und in die if 
Bedingung. Tja und da meckert die Implementation, dass ich das Signal 
nicht an zwei verschiedenen Zielen verwenden darf.

[Synth 8-5535] port <HyperRAM_RWDS> has illegal connections. It is 
illegal to have a port connected to an input buffer and other 
components. The following are the port connections :
Input Buffer:
  Port I of instance ibuf_clk_inst(IBUF) in module 
<HyperBus_IN_selectio_wiz>
Other Components:
  Port I3 of instance i_817(LUT6) in module Spartan7_revc_ram_test

Wieso ist das so, der Ausgang vom Tristate (also der Eingang in Richtung 
FPGA) sollte doch äquivalent zu dem Signal ohne Tristate sein wenn 
dieses ein in ist. Ich stelle mir das so vor, dass jetzt nur der 
Tristate umgangen wird, aber das ist anscheinend nicht so.

Edit:
Ich muss RWDS am Anfang der Transaktion auswerten, und danach muss ich 
mit RWDS die Daten übernehmen wenn gelesen wird, dann ist das also ein 
Takt wenn ich das richtig sehe.
Wie gerade beschrieben kann ich beides gleichzeitig machen wenn ich da 
ein Tristate an den Eingang setze. Wenn ich das weglasse und das nur als 
Eingang verwende geht es nicht. Wie kann ich das denn sonst lösen?

Gut, weil ich die Default Einstellungen im RAM nutze, habe ich immer 
doppelte Latenz und müsste RWDS am Anfang nicht auswerten. Aber 
eigentlich will ich meine Beschreibung so bauen, dass ich später auch 
von den Defaulteinstellungen abweichen kann um den Durchsatz zu erhöhen.

: Bearbeitet durch User
von Gustl B. (-gb-)


Lesenswert?

So, jetzt ist RWDS nur ein Eingang mit Pulldown.

Aber der ist wohl zu schwach? Selbst dann wenn der RAM IC RWDS nicht 
treiben dürfte bleibt es high. Der Pulldown ist aber da, denn man kann 
am Oszi schön sehen, dass RWDS "langsam" (ca. 500 ns) nach Masse geht 
wenn #CS am Ende wieder High ist.
Hm, damit bin ich jedenfalls unzufrieden, aber das Problem ist wohl 
nicht RWDS, sondern dass der IC das treibt, also nicht erkennt, dass ich 
lesen oder schreiben will. Vielleicht hängt der ja in einem komischen 
Zustand oder die Hardware hat einen Fehler. Versorgungsspannung ist da, 
aber ob alle Lötbällchen Kontakt haben kann ich nicht sehen.

von Michael K. (Gast)


Lesenswert?

Hallo warum verwendest du Pin PCS/PCS# das ist doch nur bei Ram mit DDR 
Center Aligned Read Strobe (DCARS) funktion welchen hast du denn?

von Gustl B. (gustl_b)


Lesenswert?

Guter Punkt!
Ich habe einen
IS66WVH8M8ALL-166B1LI
und laut Ordering Information braucht der kein PSC/#PSC. Gut, ich hatte 
das Datenblatt

The  PSC/PSC#  differential  clock is used only in  HyperBus  devices 
with 1.8  V nominal core  and  I/O voltage.  HyperBus devices with 3  V 
nominal core and  I/O voltage  use only PSC as  a  single-ended clock.

So verstanden, dass alle 1.8 V Chips das haben. Aber ist wohl nicht so. 
Gut, was habe ich jetzt gewonnen? Wenn ich mir die Pinbelegungen 
angucke, dann sind die bis auf PSC/#PSC identisch. Es müsste also 
genügen wenn ich PSC/#PSC abschalten und hochohmig mache. Aber ich 
vermute, dass ich dann noch nicht weiter bin.

von Gustl B. (-gb-)


Angehängte Dateien:

Lesenswert?

Vielen Dank Michael K. ich war aber auch tatsächlich doof. Ich hatte die 
ganze Zeit versucht von Cypress die VHDL Datei zu verwenden, aber die 
braucht diese VITAL 2000 Teile. Aber es gibt auch eine Verilog Datei 
(Anhang) und die funktioniert ohne VITAL auch mit VIVADO. Aber ob die 
fehlerfrei ist weiß ich nicht. Naja, jetzt kann ich jedenfalls versuchen 
das Verilog zu verstehen (das ist gar nicht so schwer) und so meinen 
Controller ans Laufen zu bringen. Immerhin habe ich in der Simulation 
das gleiche Verhalten wie auf der Hardware. Ist zwar nicht schön, aber 
ein Hardwarefehler wäre schlimmer.

Edit:
Ist irgendwie komisch. Manche Signale wie ca_in ändern sich schön mit 
den ersten 6 Flanken von CK, aber es werden nur 00 übernommen. Obwohl 
auf DQ ganz klar etwas anderes steht. Ja, da ist wieder ein Tristate, 
aber das habe ich nicht so ganz verstanden wie man den in Verilog 
schreibt oder wie der hier beschrieben ist.

Im Anhang ein Bildchen aus der Simulation und hier die Codestellen:

Die Ports wie eine Entity in VHDL:
1
module s27kl0641
2
    (
3
    DQ7      ,
4
    DQ6      ,
5
    DQ5      ,
6
    DQ4      ,
7
    DQ3      ,
8
    DQ2      ,
9
    DQ1      ,
10
    DQ0      ,
11
    RWDS     ,
12
13
    CSNeg    ,
14
    CK       ,
15
    RESETNeg
16
    );

Dann gibt es Wires:
1
    wire DQ7_ipd;
2
    wire DQ6_ipd;
3
    wire DQ5_ipd;
4
    wire DQ4_ipd;
5
    wire DQ3_ipd;
6
    wire DQ2_ipd;
7
    wire DQ1_ipd;
8
    wire DQ0_ipd;

Die werden dem Signal Din zugewiesen:
1
    wire [7:0] Din;
2
    assign Din = { DQ7_ipd,
3
                   DQ6_ipd,
4
                   DQ5_ipd,
5
                   DQ4_ipd,
6
                   DQ3_ipd,
7
                   DQ2_ipd,
8
                   DQ1_ipd,
9
                   DQ0_ipd};

Und so sind die Wires DQX_ipd mit DQ verbunden:
1
    buf   (DQ7_ipd , DQ7 );
2
    buf   (DQ6_ipd , DQ6 );
3
    buf   (DQ5_ipd , DQ5 );
4
    buf   (DQ4_ipd , DQ4 );
5
    buf   (DQ3_ipd , DQ3 );
6
    buf   (DQ2_ipd , DQ2 );
7
    buf   (DQ1_ipd , DQ1 );
8
    buf   (DQ0_ipd , DQ0 );

Das bedeutet doch, dass Din direkt DQ entspricht oder?!

Und hier:
1
        CA_BITS:
2
        begin
3
            if (!CSNeg &&
4
            (rising_edge_CKDiff || falling_edge_CKDiff))
5
            begin
6
                for(i=1;i<=8;i=i+1)
7
                    ca_in[ca_cnt-i] = Din[8-i];
8
                ca_cnt = ca_cnt - 8;

Werden die Daten in ca_in geschrieben.
Habe ich das bis hierhin richtig verstanden?

: Bearbeitet durch User
von Gustl B. (-gb-)


Angehängte Dateien:

Lesenswert?

OK, Sorry, das war ein Fehler von mir ...

Aber dadurch wird es noch nicht viel besser.
Die CA Daten werden korrekt übernommen, Adresse=9, RW=0 (Write), 
Target=0 (Memory).
Aber was ist RD_MODE?
1
    parameter LINEAR     = 4'd0;
2
    parameter CONTINUOUS = 4'd1;
3
    reg [1:0] RD_MODE = CONTINUOUS;

Im Datenblatt gibt es nicht LINEAR und CONTINUOUS, sondern linear und 
wrapped. Ist also CONTINUOUS = wrapped Burst?

Im Datenblatt bedeutet eine 1 linear, hier ist es genau umgekehrt.
Gibt es da irgendwelche Bedingungen dass ein Burst stattfinden darf? Ich 
meine sowas wie die Adresse muss der Anfang einer Page sein oder so.

Seltsamerweise zählt data_cycle nicht. Jetzt mal nur den Code für die 
steigende Flanke von CK:
1
        DATA_BITS:
2
        begin
3
            if (rising_edge_CKDiff && !CSNeg)
4
            begin
5
                if (Target==1'b1 && RW==1'b0)
6
                begin
7
                    Data_in[15:8] = Din;
8
                    data_cycle = data_cycle + 1;
9
                end
10
                else
11
                if (BurstDelay==0 && !PO_in)
12
                begin
13
                    RdWrStart = 1'b0;
14
                    if (RW == 1) // read
15
                    begin
16
                        glitch_rwds = 1'b1;
17
                        glitch_rwdsR = 1'b1;
18
                        RWDSout_zd_tmp = 1'b1;
19
                        if (Target == 0) // mem
20
                        begin
21
                            if (Mem[Address][15:8]==-1)
22
                                Dout_zd_tmp = 8'bxxxxxxxx;
23
                            else
24
                                Dout_zd_tmp=Mem[Address][15:8];
25
                        end
26
                        else // reg
27
                            Dout_zd_tmp = Config_reg[15:8];
28
                    end
29
                    else // (RW == 0) write
30
                    begin
31
                        Data_in[15:8] = Din;
32
                        data_cycle = data_cycle + 1;
33
                        UByteMask = RWDS;
34
                    end
35
                end
36
            end

Ich schreibe (RW=0) in den Speicher (Target=0). Ich gehe also in den 
ersten else Zeig und da wird auf BurstDelay=0 geprüft, was es aber nicht 
ist. Das behält den Wert 6. BurstDelay wird aber nur verringert wenn 
REFCOLL_ACTIV 0 ist. Und das wird nur dann 0 gesetzt wenn !REF_in 
gegeben ist. Und das wiederum wird 0 gesetzt wenn rising_edge_REF_out 
gegeben ist. Und das findet statt bei always @(posedge REF_out).
Das hängt dann aber wieder von REF_in ab?!
1
    //  Refresh Collision Time
2
    always @(posedge REF_in)
3
    begin:REFr
4
        if (SPEED100)
5
            #tdevice_REF100 REF_out = REF_in;
6
    end
7
    always @(negedge REF_in)
8
    begin:REFf
9
        #1 REF_out = REF_in;

Kann das dann überhaupt jemals eintreten?
Ich hänge nochmal die Verilogdatei an ...

: Bearbeitet durch User
von Gustl B. (-gb-)


Angehängte Dateien:

Lesenswert?

So, letztes Update für diese Nacht:

Ich habe ein Minimalprojekt geschrieben. Das macht nach 200 us einen 
Reset und danach eine Schreibtransaktion auf Adresse 9 und darauf eine 
Lesetransaktion von Adresse 9. Ja, das ist jetzt nur stumpf 
hingeschrieben, aber es ist das gleiche Timing das mein 
HyperBusController hat. Man kann also schön gucken was hier in dem RAM 
IC abgeht und warum was nicht funktioniert - das ist genau die Stelle 
die ich nicht verstehe.

von Michael K. (Gast)


Lesenswert?

Du hast RWDS nicht auf High bei dem Daten cycle also werden die Bytes 
nicht übernommen

von S. R. (svenska)


Lesenswert?

Christoph Z. schrieb:
> git clone
> make all
>
> Mehr soll nicht nötig sein (natürlich sind andere build Systeme erlaubt)

Zählt das auch, wenn dieser Schritt zwischendurch Daten aus dem Netzwerk 
nachlädt, diverse Debian-Pakete baut, durch ein systemspezifisches Tool 
(nicht Teil des Buildsystems!) jagt, daraus einen Haufen Images baut, 
diese dann wieder auseinandernimmt und neu zusammenknotet, um am Ende 
eine ZIP-Datei auszuwerfen? :-)

In dem Test liegen wir bei 7~8, wobei einige grenzwertig sind (z.B. 
"Gibt es eine Spec?" - "Darf man sie auch ignorieren/ständig 
anpassen?").

von Gustl B. (gustl_b)


Lesenswert?

Das war ein guter Tipp Michael.

Dann verstehe ich aber Seite 15 unten Fußnote 5 nicht. 
https://www.mouser.de/datasheet/2/198/66-67WVH8M8ALL-BLL-938852.pdf

The figure shows  RWDS  masking  byte  A0 and  byte  B1  to  perform an 
unaligned  word write  to bytes B0  and  A1.

Wenn da B0 und A1 geschrieben wird, dann wird doch genau das geschrieben 
bei dem RWDS 0 ist.

Werde ich daheim ausprobieren, aber ich glaube mittlerweile, dass RWDS 0 
sein muss damit die Daten geschrieben werden.

: Bearbeitet durch User
von Gustl B. (-gb-)


Angehängte Dateien:

Lesenswert?

So, ausprobiert, hat nichts verändert, kann man auch am Verilog sehen, 
da wird RWDS nicht abgefragt wenn es um Data_in geht.

von Gustl B. (gustl_b)


Lesenswert?

Noch ein Zitat zu RWDS beim Schreiben:

During the write  data transfers,  RWDS is  driven by  the  host master 
interface  as a data mask. When data is  being  written  and  RWDS is 
High the byte  will be masked  and the array  will not be altered.  When 
data  is  being  written  and  RWDS is Low the data will  be placed 
into  the  array.

Seite 14 im Datenblatt.

von Michael K. (Gast)


Lesenswert?

Hallo Gustl,

ja ist richtig RWDS muss low sein.
Das Simulation Problem ist in der Datei s27kl0641.v
parameter TimingModel = "DefaultTimingModel";
ändere das mal auf
parameter TimingModel = "S27KL0641DABHI020";

Gruss,
Michael

von Gustl B. (-gb-)


Lesenswert?

Edit, doch ändert was. Danke! In der Simulation funktionieren jetzt 
meine Bursts mit 1 und 32 Worten ohne Fehler.

: Bearbeitet durch User
von Christoph Z. (christophz)


Lesenswert?

S. R. schrieb:
> Christoph Z. schrieb:
>> git clone
>> make all
>>
>> Mehr soll nicht nötig sein (natürlich sind andere build Systeme erlaubt)
>
> Zählt das auch, wenn dieser Schritt zwischendurch Daten aus dem Netzwerk
> nachlädt, diverse Debian-Pakete baut, durch ein systemspezifisches Tool
> (nicht Teil des Buildsystems!) jagt, daraus einen Haufen Images baut,
> diese dann wieder auseinandernimmt und neu zusammenknotet, um am Ende
> eine ZIP-Datei auszuwerfen? :-)

Genau um solche Beispiele geht es! :-)

Ohne Build Automatisierung bekommt man von drei Ingenieuren vier 
verschiedene Ergebnisse...

> In dem Test liegen wir bei 7~8, wobei einige grenzwertig sind (z.B.
> "Gibt es eine Spec?" - "Darf man sie auch ignorieren/ständig
> anpassen?").

Living Specs sind ja ein altes Problem. Genau aus dieser Erkenntnis 
kommen ja die ganzen Agilen Methoden, weil Teile des V-Modells nicht mit 
der Realität zusammenpassen.

Und genau da liegen auch viele Fehlinterpretationen. Agil bedeutet genau 
gar nicht, das keine Spec da ist. Die Spec muss am Ende eines Sprints 
mit dem Release zusammenpassen (Hat hier jemand Self-documenting code 
oder executable Spec gesagt?), sonst ist der Sprint nicht abgeschlossen 
und wie sollten dann auch die Tests geschrieben werden und der nächste 
Sprint geplant werden.

von Gustl B. (-gb-)


Lesenswert?

So, Simulation funktioniert mit TimingModel = "S27KL0641DABHI020", aber 
meine Hardware ist ja ein IS66WVH8M8ALL-166B1LI und mit dem funktioniert 
es nicht (auf der Hardware).

Daher erstmal:
Das ist ja ein 166 MHz RAM, ist das trotzdem OK wenn ich den nur mit 100 
MHz betreibe? Meine Vermutung ist, dass das baugleiche ICs sind die 
selektiert werden. Die besseren werden als 166 verkauft, die 
schlechteren als 100.

Sehe ich das richtig, dass dieser Verilog Code der TimingModel auswertet 
nur darauf guckt ob in dem String ein "A" enthalten ist?
1
    begin: InitTimingModel
2
    integer i;
3
    integer j;
4
        //assumptions:
5
        //1. TimingModel has format as S27KL0641XXXXXXXX
6
        //it is important that 11-th character from first one is "G" or "P"
7
        //2. TimingModel does not have more then 24 characters
8
        tmp_timing = TimingModel;//copy of TimingModel
9
10
        i = 23;
11
        while ((i >= 0) && (found != 1'b1))//search for first non null character
12
        begin        //i keeps position of first non null character
13
            j = 7;
14
            while ((j >= 0) && (found != 1'b1))
15
            begin
16
                if (tmp_timing[i*8+j] != 1'd0)
17
                    found = 1'b1;
18
                else
19
                    j = j-1;
20
            end
21
            i = i - 1;
22
        end
23
        i = i +1;
24
        if (found)//if non null character is found
25
        begin
26
            for (j=0;j<=7;j=j+1)
27
            begin
28
            //Speed is 11.
29
                tmp_char1[j] = TimingModel[(i-10)*8+j];
30
            end
31
        end
32
        if (tmp_char1 == "A")
33
            SPEED100 = 1;
34
    end

Ja und dann finde ich von ISSI leider keine (V)HDL Beschreibungen. 
Müsste der ISSI Stein wie der Cypress Stein funktionieren weil ja 
HyperBus oder könnte es trotzdem sein, dass ich irgendetwas ansers 
machen muss?

Wäre zwar etwas Aufwand, aber ich könnte mir auch den S27KS0641DPBHI020 
kaufen und damit den ISSI Stein ersetzen.

: Bearbeitet durch User
von Michael K. (Firma: IDS) (codi78)


Angehängte Dateien:

Lesenswert?

Am besten mal die simulation mit dem s27ks0641.v model machen das auch 
DDR 166mhz unterstützt.

von Gustl B. (-gb-)


Lesenswert?

Danke! Auch damit funktioniert die Simulation wunderbar. Bei TimingModel 
habe ich S27KS0641DPBHI020 geschrieben.

Nun ... ich werde auf meiner nächsten Platine dann einen 
S27KS0641DPBHI020 verbauen und alle Signale auf Testpads routen.

von Gustl B. (-gb-)


Angehängte Dateien:

Lesenswert?

So, ich habe bei Terasic sehr versteckt ein Modell für einen ISSI STein 
gefunden. Ebenfalls in Verilog. Und zwar kann man da einige Dinge per 
ifdef einstellen. Kommentar im Code:
1
* Running Options
2
*  +S10     : Set AC timing parameter for -10(100MHz )
3
*  +S75     : Set AC timing parameter for -75(133MHz )
4
*  +S60     : Set AC timing parameter for -60(166MHz )
5
*  +VERBOSE : Display internal operation status
6
*  +OFF_ST  : Phase Shifted Clock enabled
7
*             (default : Phase Shifted Clock disable)

Und so sieht das Verilog mit den Ports und den Ifdefs aus:
1
module IS66WVH16M8ALL (ck, ckb, psc, pscb, csb, dq, rwds,resetb);
2
3
        parameter       ROW_BITS        =            14;
4
        parameter       COL_BITS        =             9;
5
        parameter       DQ_BITS         =             8;
6
  parameter       mem_cnt         =            23;
7
        parameter   mem_width      =             8;
8
        parameter       mem_sizes       =       8388607;
9
        parameter  VT    =        1;  
10
11
// Timing Parameter -10 PC100
12
13
    `ifdef S10
14
15
        parameter       tCK            =  10;
16
        parameter       tRFH           =  40;
17
        parameter       tPO            =  40;
18
        parameter       tDSS           =  0.8;
19
        parameter       tDSH           =  0.8;
20
        parameter       tIS            =  1.0;
21
        parameter       tIH            =  1.0;
22
        parameter       tRWR           =  40;
23
        parameter       tCSHI          =  10;
24
        parameter       tCK2RWDS       =  3.0;
25
  parameter       SS             =  1;
26
     `endif
27
28
// Timing Parameter -75 PC133
29
30
     `ifdef S75
31
32
        parameter       tCK            =  7.5;
33
        parameter       tRFH           =  37.5;
34
        parameter       tPO            =  37.5;
35
        parameter       tDSS           =  0.6;
36
        parameter       tDSH           =  0.6;
37
        parameter       tIS            =  0.9;
38
        parameter       tIH            =  0.9;
39
        parameter       tRWR           =  37.5;
40
        parameter       tCSHI          =  7.5;
41
        parameter       tCK2RWDS       =  3.0;
42
        parameter       SS             =        1;
43
     `endif
44
45
// Timing Parameter -60 PC166
46
47
     `ifdef S60
48
49
        parameter       tCK            =  6;
50
        parameter       tRFH           =  36;
51
        parameter       tPO            =  36;
52
        parameter       tDSS           =  0.45;
53
        parameter       tDSH           =  0.45;
54
        parameter       tIS            =  0.8;
55
        parameter       tIH            =  0.8;
56
        parameter       tRWR           =  36;
57
        parameter       tCSHI          =  6;
58
        parameter       tCK2RWDS       =        3.0;
59
        parameter       SS             =        1;
60
61
62
    `endif 
63
  parameter MEM_INIT_EN = 0;
64
  
65
// Timing Parameter 
66
67
  parameter       tCSS            =  3.0;
68
  parameter  tCSM    =  4e3;
69
  parameter  tRP    =  200;
70
  parameter  tRH    =  200;
71
  parameter  tRPH    =  400;
72
  `ifdef SPEEDSIM
73
  parameter  tVCS    =  10e3; 
74
  `else
75
  parameter  tVCS    =  150e3; 
76
  `endif
77
  parameter  tDPDIN    =  10e3; 
78
  parameter  tDPDOUT    =  150e3; 
79
  parameter  tDPDCSL    =  200;  
80
  parameter  tCKDS    =  2.78; 
81
82
83
84
        `define MAX_BITS   (ROW_BITS+COL_BITS-1)
85
86
87
88
    // ports
89
    input                       ck;
90
    input                       ckb;
91
    input                       psc;
92
    input                       pscb;
93
    input                       csb;
94
    input      resetb;
95
    inout         [DQ_BITS-1:0] dq;
96
    inout      rwds;     
97
98
    `protect
99
100
    `ifdef VERBOSE
101
  wire  Debug  = 1'b1;  
102
    `else
103
  wire  Debug   = 1'b0;
104
    `endif
105
106
107
    `ifdef OFF_ST
108
  wire  IDR_Off_st = (SS==1)? 1'b1: 1'b0;
109
    `else
110
  wire  IDR_Off_st = 1'b0;  
111
    `endif

Wie kann ich das in meine VHDL Testbench einbinden? Die Inputs sind mir 
klar, aber die ifdefs, sind das Generics?

Bedeutet z. B.
`ifdef S10
dass es ein Generic mit dem Namen "S10" gibt und wenn das '1' ist ist 
das gesetzt und bei '0' nicht gesetzt/erfüllt? Und welchen Typ hat das 
Generic?

Edit:
Generics wie
1
component IS66WVH16M8ALL is 
2
  generic(
3
  S10: boolean;
4
  S75: boolean;
5
  S60: boolean;
6
  SPEEDSIM: boolean;
7
  VERBOSE: boolean;
8
  OFF_ST: boolean);
9
  port(
10
    ck: in std_logic;
11
    ckb: in std_logic;
12
    psc: in std_logic;
13
    pscb: in std_logic;
14
    csb: in std_logic;
15
    resetb: in std_logic;
16
    dq: inout std_logic_vector(7 downto 0);
17
    rwds: inout std_logic);
18
end component;

funktionieren leider nicht.

Und noch ein Edit:
Ich habe jetzt das Verilog so editiert, dass die Parameter einfach fest 
sind ohne Ifdefs. Und siehe da, die Simulation funktioniert auch hier 
... hm ... sieht tatsächlich nach einem Hardwareproblem aus.
Im Anhang noch das Verilogmodell von Terasic, dort ist es in dem ZIP 
https://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=English&CategoryNo=253&No=1140&PartNo=3 
enthalten.

Edit2:
Edit3: Edit2 entfernt^^ Simulation läuft problemlos ohne Fehlermeldung 
im Verbose Modus mit den 166 MHz Timings im Verilogmodell aber nur 100 
MHz CK/#CK.

Vielen Dank!

: Bearbeitet durch User
von Gustl B. (-gb-)


Angehängte Dateien:

Lesenswert?

Es war die Hardware. Erhitzen hat nicht geholfen, also habe ich den IC 
getauscht gegen einen baugleichen (ISSI). Jetzt funktioniert das 
wunderhybsch.

Im Anhang das Projekt für die Simulation mit den Verilogmodellen die ich 
finden konnte. Mit dabei ist mein "HyperBus Master". Den habe ich 
möglichst einfach gehalten:
1
entity HyperBus is Port(
2
  clk100: in std_logic;
3
  start: in std_logic;
4
  mem_regs: in std_logic; --0: Mem, 1: Regs
5
  burstlength: in std_logic; --0: 2Bytes, 1:64Bytes
6
  adr: in std_logic_vector(21 downto 0); -- 21 ... 9: 8192 Rows, 8 ... 0: 512 Words in 1 Row. (2 ... 0: 8 Words = 1 Half Page)
7
  snd_rcv: in std_logic; --0: send/write, 1: receive/read
8
  ready: out std_logic;
9
  --- SND ---
10
  data_snd: in std_logic_vector(64*8-1 downto 0);
11
  --- RCV --
12
  data_rcv_valid: out std_logic;
13
  data_rcv: out std_logic_vector(64*8-1 downto 0);
14
  --- RAM ---
15
  nReset: out std_logic;
16
  nCS: out std_logic;
17
  CK: out std_logic;
18
  nCK: out std_logic;
19
  PSC: out std_logic;
20
  nPSC: out std_logic;
21
  RWDS: inout std_logic;
22
  DQ: inout std_logic_vector(7 downto 0));
23
end HyperBus;

clk100 ist der Systemtakt,
start sagt dass es losgehen soll und Daten/Adresse anliegt.
mem_regs sagt ob aus dem RAM oder dessen Registern gelesen werden soll 
(Schreiben der Register ist nicht unterstützt!).
burstlength sagt ob 1 Wort oder 32 Worte gelesen/geschrieben werden 
sollen.
adr ist die adresse.
snd_rcv sagt ob geschrieben oder gelesen werden soll.
ready sagt ob die Komponente bereit ist.
data_snd sind die zu schreibenden Daten,
data_rcv_valid sagt ob die gelesenen Daten data_rcv aktuell sind. Dabei 
ist aber data_rcv_valid nur für genau einen Takt lang '1' nach einem 
Lesevorgang.
Die restlichen Anschlüsse betreffen die Hardware. Dabei wird PSC/nPSC 
jetzt mit 'Z' belegt weil ich das angeschlossen habe. Aber der im 
Projekt enthaltene MMCM erzeugt auch PSC. Man kann also mit der 
Beschreibung auch HyperRAM Steine betreiben die PSC benötigen. In diesem 
MMCM kann man auch schön CK/nCK gegenüber DQ verschieben (über die 
Phase) damit die Taktflanke dann wirklich mittig in den Daten liegt.

In der Simulation geschieht bei grob 650 us ein Reset (den mach mein 
HyperBus Controller immer wenn er losläuft, kann man auch rauslöschen). 
Dann bei 660 us gibt es einen 32 Wort Schreibvorgang und bei 662 us 
einen 32 Wort Lesevorgang.

Ein 32 Wort Burst dauert 480 ns, dann muss nCS noch für mindestens einen 
Takt '1' sein, macht zusammen 490 ns für 64 Bytes. Und (1/490ns)*64Bytes 
= 130,6 MBytes/s. Damit liegt das jetzt knapp über meinem Ziel, ich 
wollte auf jeden Fall die Daten meiner ADCs wegschreiben können (100 
MByte/s) und als "nett zu haben" auch noch schneller sein als Gigabit 
Ethernet falls ich das mal verwende mit dem FPGA.

Ja, sonst ... darf gerne verwendet und modifiziert werden. Bei Fragen 
einfach fragen.

von Gustl B. (-gb-)


Lesenswert?

Nachtrag:
Ich suche gerade nach einem Hyperram IC der bei 3.3 V funktioniert. 
Solche gibt es von Cypress, ISSI und Winbond. Die Datenblätter sehen 
sich jeweils sehr ähnlich und die ICs funktionieren bis 3.6 V.

Aber: Die von Cypress und ISSI gehen in der 3 V Version nur bis maximal 
100 MHz (bei 1.8 V bis 166 MHz).
http://www.issi.com/WW/pdf/66-67WVH8M8ALL-BLL.pdf
https://www.cypress.com/file/183506/download/001-97964_S27KL0641_S27KS0641_S70KL1281_S70KS1281_3.0_V_1.8_V_64_Mb_8_MB_128_Mb_16_MB_HyperRAM_TM_Self-Refresh_DRAM.pdf

Bei Winbond hingegen sind die ICs noch ganz frisch, das Datenblatt 
stammt von letztem Herbst und dort gehen die ICs bei 1.8 V und 3.3 V bis 
200 MHz.
https://www.mouser.de/datasheet/2/949/W956x8MBYA_64Mb_HyperBus_pSRAM_TFBGA24_datasheet_A-1760356.pdf

Ich werde also zwei der Winbond ICs in meiner nächsten Schaltung 
einplanen.
Ob ich diese Geschwindigkeit benötige weiß ich nicht, das hängt davon ab 
was ich über USB3 mit dem FT600 an Durchsatz hinbekomme. Theoretisch 
gehen 200 MByte/s und da würden mir die 100 MHz am RAM nicht mehr 
ausreichen.

von Gustl B. (-gb-)


Lesenswert?

Und noch was:
Ich sehe gerade, dass es auch Flash ICs gibt die einen HyperBus 
verwenden. Das sieht auch nicht so irre kompliziert aus.

Hat hier jemand schon mal einen solchen HyperFlash IC verwendet?

Ein Datenblatt:
https://www.mouser.de/datasheet/2/100/512_MBIT_256_MBIT_128_MBIT_HYPERFLASH_FAMILY_Datas-957657.pdf

von Duke Scarring (Gast)


Lesenswert?

Gustl B. schrieb:
> Theoretisch gehen 200 MByte/s und da würden mir
> die 100 MHz am RAM nicht mehr ausreichen.
Du kannst auch zwei RAM-Chips nehmen und parallel ansteuern...

von Gustl B. (gustl_b)


Lesenswert?

Das ist auch der Plan. Aber ich weiß noch nicht genau was sonst noch auf 
die Platine soll. Ich würde gerne was mit SerDes machen. Da bieten sich 
schnelle ADCs oder DACs an. HDMI ginge auch.
Aber da Laufe ich dann vermutlich in das Problem, dass HDMI ja LVDS out 
ist und ich dafür die Bank am FPGA auf 2.5 V legen muss. Damit geht dann 
an dieser Bank kein HyperRAM.
Schneller ADC ginge, aber da werde ich mehrere RAMs brauchen. Wenn ich 1 
GByte/s in den Samplespeicher schreiben will reichen mir 4 RAMs mit je 
250 MByte/s. Und die bekomme ich bei 166 MHz und mindestens 128 Byte 
langen Bursts oder auch mit 200 MHz und 64 Byte Bursts.
Statt ADC könnte ich auch zwei weitere USB-C Buchsen verbauen. Das wären 
dann 8 LVDS Pärchen. Mit einem LVDS fähigen schnellem Komparator am 
anderen Ende des USB-C Kabels könnte ich so einen schnellen 
Logikanalysator bauen.
Wenn du weiter Ideen für ein Bastel-lernprojekt hast immer her damit. 
Hauptsächlich will ich einmal USB-C mit USB3 gemacht haben. Aber da 
bleiben eben noch einige IOs übrig.

Leider sieht aktuell die Verfügbarkeit von ICs, z. B. dem HyperRAM echt 
mies aus. Die 3 V Variante bekommt man gar nicht.

Und 1.8 V gehen nicht weil an der Bank auch das Konfigurationsflash 
hängt und das mag 3.3 V.
Alles nicht so einfach, aber Luxusprobleme.

von Gustl B. (-gb-)


Lesenswert?

Aber wenn ich schon beim Planen bin, sollte ich lieber den 1.8 V oder 
den 3.0 V RAM verwenden (beides 200 MHz RAMs)? Strom und Kosten sind mir 
an der Stelle egal, mir geht es drum bei welcher Spannung ich 
"problemloser" den höheren/maximal möglichen Takt erreiche.

von Duke Scarring (Gast)


Lesenswert?

Spricht etwas gegen DDR2 oder DDR3-RAMs?

Duke

von Gustl B. (-gb-)


Lesenswert?

Hm, eigentlich nicht wirklich, aber:

- Ich habe nur zwei halbe Bänke - geht das? Und welche Bankspannungen 
sind erlaubt?

- Da muss ich wohl AXI verwenden?!

- Ich habe das jetzt mal mit dem MIG bauen lassen und zähle 36 IOs die 
das braucht. Das ist weniger wie 4x HyperRAM. Wobei ... bei 4x Hyperram 
könnte ich doch CK (die wohl lieber nicht), CS# und Reset# untereinander 
verbinden und bin dann 39 IOs für alle 4. Hm ... Hm ...

- Das könnte vom Layout her ziemlich fies werden, wäre aber eine neue 
Herausforderung nachdem HyperRAM jetzt abgehakt ist (-:

Edit:
Kann man einen DDR2/3 auch langsamer betreiben wenn das Layout nicht für 
den hohen Takt gut genug ist? Beim HyperRAM geht das recht problemlos. 
Ich habe gerne Dinge die zur Not zumindest noch ein bischen 
funktionieren ...

: Bearbeitet durch User
von Tobias B. (Firma: www.elpra.de) (ttobsen) Benutzerseite


Lesenswert?

Gustl B. schrieb:
> Kann man einen DDR2/3 auch langsamer betreiben wenn das Layout nicht für
> den hohen Takt gut genug ist? Beim HyperRAM geht das recht problemlos.
> Ich habe gerne Dinge die zur Not zumindest noch ein bischen
> funktionieren ...

Nicht mit dem Xilinx MIG. Der braucht einen Mindestakt damit er bei der 
Kalibrierung zumindest ein komplettes Datenauge samplen kann.

von Gustl B. (-gb-)


Lesenswert?

Gustl B. schrieb:
> - Ich habe nur zwei halbe Bänke - geht das? Und welche Bankspannungen
> sind erlaubt?

Der MIG meckert bei zwei halben Bänken ... aber gut, dann muss ich eben 
andere Dinge umplanen.

DDR3 braucht 1.5 V und wäre auch sonst recht schick. Aber was mache ich 
dann mit den restlichen IOs an der Bank? Für 1.5 V gibt es leider kaum 
ICs die ich noch verbauen könnte. DDR2 geht mit 1.8 V, das ist schon 
feiner.

Gustl B. schrieb:
> - Da muss ich wohl AXI verwenden?!

Muss man nicht. Auch schick! Hach ...

Tobias B. schrieb:
> Nicht mit dem Xilinx MIG. Der braucht einen Mindestakt damit er bei der
> Kalibrierung zumindest ein komplettes Datenauge samplen kann.

OK, aber kann ich da einen DDR2 800 verwenden und den MIG erstmal für 
einen DDR2 400 konfigurieren und mich dann langsam an die 800 MHz 
rantasten?

Und dann möchte ich noch die tatsächliche Datenrate abschätzen können. 
Bei Wikipedia steht z. B. 3.2 GB/s für den DDR2 400 und 64 Bit Breite.
Ist klar, 8 Bytes * 400 M = 3.2 GByte.
Aber das ist doch dann nur die Maximaldatenrate während eines Bursts. 
Was schafft denn der RAM im zeitlichen Mittel?
Bei 8 Bit Datenbus sind das dann 400 MByte/s beim Burst.

Beim HyperRAM mit 200 MHz werden auch die 400 MByte/s angegeben, aber 
das ist leider auch nur Burst und nicht Durchschnitt. Beim HyperRAM geht 
aber nicht mehr wie 200 MHz IO Takt, beim DDR2 schon, da geht es mit 200 
MHz erst los und geht bis 533 MHz.

von Duke Scarring (Gast)


Lesenswert?

Gustl B. schrieb:
> Aber das ist doch dann nur die Maximaldatenrate während eines Bursts.
Ja.

> Was schafft denn der RAM im zeitlichen Mittel?
Das hängt von Deinem Zugriffsmuster ab. Wenn aus jedem Burst nur ein 
Byte rausgeholt wird, geht die Rate deutlich in den Keller.

Duke

von Gustl B. (-gb-)


Lesenswert?

Noch ein paar Überlegungen zur Datenrate je FPGA IO:

Der HyperRAM macht bei mir bei 100 MHz und 64 Byte Bursts 130.6 MByte/s. 
Dafür werden 13 FPGA IOs benötigt. Macht also grob 10 MByte/IO.

Bei 200 MHz und 256 Byte langen Bursts macht der RAM 353.1 MByte/s im 
Schnitt. Das sind grob 27 MByte/s im zeitlichen Mittel.

DDR2 mit 8 Bit Datenbus benötigt 35 IOs und schafft. Bei DDR2_400 400 
MByte/s. Das sind dann 11.4 MByte/ IO. Bei DDR2_800 sind es also 22 
MByte/IO. Und leider kann mein Spartan7 sogar nur DDR2 bis 667 MHz.

Und in diesem Vergleich haben wir die durchschnittliche Datenrate beim 
HyperRAM und die Burst Datenrate vom DDR2 verglichen.

Mit 3 HyperRAM ICs komme ich bei den 200 MHz und den längeren Bursts im 
Schnitt auf über 1 GByte/s, bei DDR2_800 nicht. Die 3 HyperRAMs breichen 
39 IOs, der DDR2 35. Bei den HyperRAMs gibt es auch welche die nur eine 
single-ended Clock haben, das ist dann 1 IO weniger je IC und ich könnte 
auch die Resets untereinander verbinden.

Eigentlich reichen mir auch 2 HyperRAMs. Ich muss halt die 200 MByte vom 
FT600 wegschreiben können und ich würde gerne HDMI machen. Da der 
Spartan7 sowieso keine irre schnellen SerDes hat lange ich bei einer 
Pixelclock vermutlich unter 100 MHz. Das sind dann 300 MByte/s bei RGB 
maximal.

Ja, ich verwe jetzt nochmal HyperRAM verbauen und meinen Controller 
umbauen dass der ein FIFO Interface hat und einen höheren Takt kann. 
Vielleicht per Generic einstellbar welches HyperRAM Modell man bei 
welchem Takt verwenden will.

: Bearbeitet durch User
von J. S. (engineer) Benutzerseite


Angehängte Dateien:

Lesenswert?

Gustl B. schrieb:
> Bei 200 MHz und 256 Byte langen Bursts macht der RAM 353.1 MByte/s im
> Schnitt. Das sind grob 27 MByte/s im zeitlichen Mittel.

Geht noch etwas mehr???  Ich bin da bwegen meiner Workstation auch 
gerade dran und hatte schon probiert full HD auszulesen, um einen echten 
frame buffer zu haben, in den man auch offline zeichnen kann. Müssten 
netto rund 356MB/s sein - siehe Tabelle.

Für den Audio-Betrieb wird es bei mir aber wohl nur die halbe Auflösung 
bei 12 Bit werden, damit ich mehr Bilder reinbekomme. Mein RAM hat nur 
64Mbit. Zudem werden es gfs nur 30Hz.

Der RAM-Baustein ist aber prima, für solche Anwendungen, weil er nicht 
so arg viele PINs verschluckt.

von Gustl B. (-gb-)


Lesenswert?

Tja ausprobieren. Etwas mehr Takt geht sicher und sonst kannst du 
einfach noch einen Baustein parallel anbinden. Kostet nur weitere 12 
IOs.

von J. S. (engineer) Benutzerseite


Lesenswert?

Werde es demnächst mal wieder anpacken und schauen, ob es geht. Für den 
Controller gibt es ein update. Mehr Pins geht nicht, da nicht vorhanden. 
Das PCB ist fix designed. Mit einem Baustein.

von Gustl B. (-gb-)


Lesenswert?

Keine Ahnung ob sich bei dir was getan hat, aber Winbond nennt hier im 
Datenblatt 
https://www.mouser.de/datasheet/2/949/W958D8NBYA_256Mb_HyperRAM_TFBGA24_SDP_85C_datashee-3073409.pdf 
jetzt einen Maximaltakt von 250 MHz und somit 500 MBit/s je Datenpin.
Ich hatte das damals so gemacht 
Beitrag "HyperBus Ideen"

: Bearbeitet durch User
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.