Forum: FPGA, VHDL & Co. VHDL-Code und Modularisierung


von Knut E. (knulli)


Lesenswert?

Hi,

ich will an meinem Projekt mal üben, wie man das mit der Modularisierung 
bei größeren Projekten so macht.

Ich hab hier gerade einen FTDI-FIFO und einen NAND-Flash die beide über 
einen CoolRunner-II zusammengestrickt werden sollen.

Ich hätte das genz gerne so gemacht, daß in meiner Main-Entität 
eigentlich nur noch der "Main-Controller" steckt. Der soll die Daten und 
Steuerleitungen vom FTDI zum NAND-Flash und umgekehrt handeln.

Was ich ganz gerne hätte, wäre z.B. so eine Art Entität FTDI, die nur 
noch einen bidirektionalen Datenbus und ein paar Steuerleitungen hat und 
die ganzen SM's und auch die Connectivity zur Außenwelt in sich kapselt, 
so daß der "Benutzer" von FTDI sich nicht mehr mit irgendwelchen 
Strippen von und zum FTDI-Chip kümmern muß.

Bei meinen ersten Gehversuchen mit VHDL und dem FTDI war es idR. so, daß 
ich eine einzige Entität hatte, deren Port die Strippen zur Außenwelt 
waren. Sollten nun noch weitere Entitäten mit angeschlossen werden, habe 
ich bisher die Liste verlängert, eine übergeordnete Entität erzeugt und 
die hat dann die Kommunikation zur Außenwelt per ucf gemacht und zur 
anderen Entität per select Anweisung usw.

entity FTDI is Port (
  -- Interface zum FTDI-Chip
  CLK:         in STD_LOGIC;                      -- Clock Eingang
  RXF:         in STD_LOGIC;                      -- RX-Flag
  TXE:         in STD_LOGIC;                      -- TX Enable
  RD:         out STD_LOGIC;                      -- Read
  WR:         out STD_LOGIC;                      -- Write
  OE:         out STD_LOGIC;                      -- Output Enable
  FTDIData: inout STD_LOGIC_VECTOR(7 downto 0);   -- 8 Bit Datenbus

  -- Interface zum Main-Controller
  CLKOut:     out STD_LOGIC;                     -- Clock Ausgang zu den 
anderen Entitäten
  RST:         in STD_LOGIC;                     -- Rest von PCB
  RDY:        out STD_LOGIC;                     -- Ready (for transmit 
Data)
  MainData: inout STD_LOGIC_VECTOR(7 downto 0)); -- 8 Bit Datenbus
end FTDI;

Das hat aber zur Folge, daß die übergeordnete Entität sich auch mit 
Leitungen "beschäftigen" muß, die sie eigentlich nit zu interessieren 
bräuchte.

Wie ist hier der richtige Design-Ansatz?

Knulli

von Duke Scarring (Gast)


Lesenswert?

Knut E. schrieb:
> Was ich ganz gerne hätte, wäre z.B. so eine Art Entität FTDI, die nur
> noch einen bidirektionalen Datenbus und ein paar Steuerleitungen hat und
> die ganzen SM's und auch die Connectivity zur Außenwelt in sich kapselt,
> so daß der "Benutzer" von FTDI sich nicht mehr mit irgendwelchen
> Strippen von und zum FTDI-Chip kümmern muß.
So richtig gut, wie Du Dir das vorstellst, wird es nicht gehen.
Ich versuche mir immer folgendes Denkmodell (bezüglich der 
Funktionsblöcke) zu verinnerlichen:

Mein programmierbarer Baustein (FPGA, CPLD) entspricht einer 
Leiterplatte und ein Modul entspricht einem Chip. Und die Signale, die 
an einem Verbindungsstecker (IO-Pin) auftauchen, müssen über die 
Leiterplatte bis zu der Stelle geführt werden, wo sie gebraucht werden.

Um nicht zu viele Signale über so viele Modulgrenzen führen zu müssen, 
verwende ich records.
Skizziert ist das Ganze z.B. in [1] "flexible interfaces", Seite 81-85
oder in [2] Seite 13.

Duke

[1] http://www.imd.uni-rostock.de/lehre/vlsi_i/tex/vhdl.pdf
[2] http://www.gaisler.com/doc/structdes.pdf

von Knut E. (knulli)


Angehängte Dateien:

Lesenswert?

Hi Duke,

um mit Deinen Worten zu sprechen:
Ich will eine Leiterplatte haben, die ins System rein nur das 
liefert/braucht, was das System betrifft, nach hinten hin soll aber noch 
ein anderes Modul rangepiekt werden können (z.B. FTDI).

Ich hab mal ein Bild davon gemacht. Es geht um die Entität FTDI. Die 
soll zum Controller hin nur den (einen) 8Bit Datebbus haben, der evtl. 
nur in Richtung Entität FTDI geht und noch ein paar Leitungen wie Ready 
(FTDI Sendepuffer ist leer) oder Start (PC sagt es geht los) usw. Zum 
FTDI-MiniModul selber sollen alle Leitungen gehen, die der FTDI so 
braucht.

Wie gestalte ich das, daß derjenige, der die Entität FTDI instanziiert, 
sich nicht mit den Leitungen zum MiniModul beschäftigen muß? Das soll 
die Entität FTDI kapseln.

Ich seh mir jetzt mal Deine Links an...


Knut

von Lattice User (Gast)


Lesenswert?

Knut E. schrieb:
> Wie gestalte ich das, daß derjenige, der die Entität FTDI instanziiert,
> sich nicht mit den Leitungen zum MiniModul beschäftigen muß? Das soll
> die Entität FTDI kapseln.

Das geht nicht.
Um bei der Leiterplattenanalogie zu bleiben, da kannst du dem Layouter 
auch nicht abnehmen sich um die Leitungen zum USB Anschluss zu kümmern, 
selbst wenn das immer wieder das gleiche ist.

von Knut E. (knulli)


Lesenswert?

Hab verstanden,
ich muß also alle Signale von und nach außen durch die Entität Main zu 
den einzelnen Modulen durchschleifen. Richtig?

Sozusagen das gesamte Mainboard in die Top-Level-Entität quetschen. 
Urrgghh...

Nunja, dafür muß ich mit VHDL die Gatter auch nicht mehr aus einzelnen 
Transitoren zusammenlöten. Und die Röhrensockel können auch im Keller 
bleiben... :-)

Knulli

von Knut E. (knulli)


Lesenswert?

So, bin zurück von meinen Lehrgängen [1] und [2]...

Ist ja ne richtige Fibel. Da muß ich wohl erstmal den Reset-Knopf in 
meinem Kopf drücken. Ein Glück, daß ich das nicht erst in 5 Jahren 
gelesen habe.

Danke für die Links.

Knulli

von Knut E. (knulli)


Lesenswert?

Hi Duke,
nochmal ne Frage zu deinen Links.

Da steht ja drin, daß man records benutzen soll und daß man In und Out 
trennen soll und daß man außer in der Top-Entität kein InOut nehmen 
soll.

Nun die Frage: Die Steuerung solcher Leitungen mit Lesen  Schreiben  
hochohmig setzen usw. ist ja etwas, was ich gerade in den 
untergeordneten Entitäten haben will.

Wie machst Du sowas?

Knulli

von Christian R. (supachris)


Lesenswert?

Das macht man mit _I _O und _T. _T dienst dann zur Steuerung des 
Tristates im Top-Level. Ist ja dann nur noch eine when Anweisung.

von Duke Scarring (Gast)


Lesenswert?

Genau. Bei mir steht dann z.B sowas im top level:
1
    -- out
2
    phy_mdc         <= etho.mdc;
3
4
    -- in
5
    ethi.mdio_i     <= phy_mdio;
6
    -- inout
7
    phy_mdio        <= etho.mdio_o when etho.mdio_oe = '0' else 'Z';

Duke

von Knut E. (knulli)


Lesenswert?

In Bezug auf z.B. einen bidirektionalen Datenbus bedeutet das dann also:

Nur noch die (Out-)Leitung zur Richtungsumkehr + Hochohmig setzen von 
der untergeordneten Entität zur Top-Level Entität führen und der 
Datenbus bleibt komplett draußen.

Richtig verstanden?

Knulli

von Duke Scarring (Gast)


Lesenswert?

Knut E. schrieb:
> Nur noch die (Out-)Leitung zur Richtungsumkehr + Hochohmig setzen von
> der untergeordneten Entität zur Top-Level Entität führen und der
> Datenbus bleibt komplett draußen.
>
> Richtig verstanden?
Ja :-)

von Wat (Gast)


Lesenswert?

>Entität

Entity hört sich undeutscher an ;-)

von Knut E. (knulli)



Lesenswert?

Hab noch ein Problem:

habe brav meine Typen/Records definiert. Zum besseren Einbinden in 
diverse vhd-Dateien hab ich's in Global.vhd gepackt.

Irgendwie will das aber nicht durch's Translate.

Scheint irgendwie daran zu liegen, daß in der Top-Level-Entity diese 
Typen nicht so gerne gesehen werden :-( .

Was ist hier richtig? FTDIData.Data(0)...FTDIData.Data(7) im .ucf geht 
nicht.

Hab für eine schnellere Überprüfung mal zwei Projekte gezippt. 
Wesentlicher Unterschied ist Zeile 41/42 und 71/72 in 
MainController.vhd.

Mal als std_logic_vector, mal als TDataBus. Letzteres will sich nicht 
"translaten" lassen. Außerdem zickt der PACE-Editor beim Aufruf rum.

Knulli

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Knut E. schrieb:
> Scheint irgendwie daran zu liegen, daß in der Top-Level-Entity diese
> Typen nicht so gerne gesehen werden :-(
Logisch.
Wie sieht denn ein Pin Location Constraint für einen std_logic aus?
> Außerdem zickt der PACE-Editor beim Aufruf rum.
Wie sieht denn ein Pin Location Constraint für einen Record aus?
Und als Konsequenz:
Warum kommt Translate nicht damit klar?
Kurz&kompakt:
Weil Records an den Bausteingrenzen (=Pins) nicht einsetzbar sind.

von franke (Gast)


Lesenswert?

hi

hab zwar keine ISE hier, aber...

schau mal, dass die Global.vhd die erste Datei in deinem Projekt ist die 
ISE compiliert, und nicht irgendwann später kommt.
Daran klemmt es zumindest bei so Fällen im Diamond...

Gruß

von Ralf (Gast)


Lesenswert?

Lothar Miller schrieb:
> Knut E. schrieb:
>> Scheint irgendwie daran zu liegen, daß in der Top-Level-Entity diese
>> Typen nicht so gerne gesehen werden :-(
> Logisch.
> Wie sieht denn ein Pin Location Constraint für einen std_logic aus?
>> Außerdem zickt der PACE-Editor beim Aufruf rum.
> Wie sieht denn ein Pin Location Constraint für einen Record aus?
> Und als Konsequenz:
> Warum kommt Translate nicht damit klar?
> Kurz&kompakt:
> Weil Records an den Bausteingrenzen (=Pins) nicht einsetzbar sind.

Das ist genau der Grund warum ich mit diesem Record-Gedoens
wieder aufgehoert habe. Wenn man naemlich die Cores allgemein
schreibt und immer wieder verwenden will, ist der Aufwand mit
den Records groesser. Deshalb habe ich mir angewoehnt
nur std_logic bzw. std_logic_vector in der Entity zu uebergeben, im
generic sind auch andere Parameter wie Real, Integer,
Natural usw. moeglich.
Im Core selbst kann man natuerlich Records verwenden, aber ob
das dann noch sinnvoll ist...

Ralf

von franke (Gast)


Lesenswert?

naja... ich übergebe z.B. eine 15x15 Matrix mit je 16-bit Werten in 
diverse Components...

viel spaß beim auscodieren...
bei mit ist das eine Zeile, sonst eher 225.


Gruß

von Ralf (Gast)


Lesenswert?

franke schrieb:
> naja... ich übergebe z.B. eine 15x15 Matrix mit je 16-bit Werten in
> diverse Components...
>
> viel spaß beim auscodieren...
> bei mit ist das eine Zeile, sonst eher 225.
>
>
> Gruß

Auscodieren musst du so oder so, was du dir sparst
ist die Parameterbeschreibung in der Entity, und die
kann man einfach mit Copy & Paste einfuegen.

Aber ich schrieb ja, wenn ich Cores wiederverwenden
will...
Oft kommen dann ein paar Signale dazu oder werden
nicht benoetigt und dann gehen die Aenderungen los.

Ralf

von Knut E. (knulli)


Lesenswert?

So, schon wieder ne Sackgasse:

Wenn ich in meinen Entitäten (Entities?) all die Datenbusse draußen 
lasse, komme ich bei meinem Flash-Interface nicht mehr weiter. Also 
Umschalten von In auf Out oder Z läßt sich ja alles noch mit einzelnen 
Steuerleitungen realisieren. Nun habe ich aber auch noch mehr als Daten 
von links nach rechts oder umgekehrt durch den Datenbus zu schicken, 
sondern auch z.B. noch Commandbytes.
Also bei nem Flash-Speicher gibts nen BiDi Datenbus der beim Lesen Daten 
"produziert", beim Schreiben Daten "verschluckt" und damit er das macht 
was er soll, muß ich ihm auch Befehlscode-Sequenzen schicken. Sowas soll 
natürlich alles in den Entities verschwinden. Wenn der Datenbus 
"draußen" bzw. in der Top-Level entity bleiben soll, wie mache ich das 
denn jetzt mit meinen Commend-Sequenzen?

Knulli

von Duke Scarring (Gast)


Lesenswert?

Knut E. schrieb:
> Also bei nem Flash-Speicher gibts nen BiDi Datenbus der beim Lesen Daten
> "produziert", beim Schreiben Daten "verschluckt" und damit er das macht
> was er soll, muß ich ihm auch Befehlscode-Sequenzen schicken. Sowas soll
> natürlich alles in den Entities verschwinden.
Woher kommen denn die Befehlscodesequenzen?
Kannst Du uns mal ein Bild davon malen, welche Modularisierung Dir 
bisher vorschwebt?

Duke

von Knut E. (knulli)


Angehängte Dateien:

Lesenswert?

>Woher kommen denn die Befehlscodesequenzen?

Die Befehlscode-Sequenz ist ein "Zusammenkleben" von Command-Bytes, die 
aus der FSM generiert werden und ein paar Adressbytes, die vom FTDI per 
USB empfangen werden (aber auch von der FSM gesendet werden sollen).
Zur Vereinfachung wollte ich aber in einem ersten Schritt alle Bytes per 
FSM generieren lassen. Das würde im FTDI-Teil das Zwischenspeichern der 
Adressbytes sparen.
Bleibt aber trotzdem im Flash-Teil die Umschalterei zwischen Data, 
FTDI-Data, Commands und die Richtungsumkehr In bzw. Out, ggf. mit "Z". 
Wenn ich das alles "draußen" lassen soll, bleibt nicht mehr viel, was 
man in die Entität packen könnte.

Warum gibts eigentlich diese Regel "InOut nur in Top-Entitäten"?

Knulli

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Knut E. schrieb:
> Entitäten (Entities?)
Zweiteres...
Nimm ruhig das englische Wort, wenn das Deutsche nur eine unnötige 
Begriffsverwirrung mit sich bringen würde. Ich muss auch nicht unbedingt 
Kellerspeicher statt Stack gesagt haben...

von Duke Scarring (Gast)


Lesenswert?

Knut E. schrieb:
> Warum gibts eigentlich diese Regel "InOut nur in Top-Entitäten"?
inout wird für bidirektionale Signalleitungen gebraucht.
Interne tristate Leitungen ('Z') gibt es nicht mehr (seit Spartan3). Im 
FPGA hat jede Leitung genau eine Quelle und ggf. mehrere Senken. Interne 
Signale können nur den Zustand 0 oder 1 annehmen. Der Synthesizer wird 
bei der internen Verwendung von inout (im Zusammenhang mit 'Z') 
Hilfskonstukte (Multiplexer/ Arbitrierer) generieren. Das kann man auch 
gleich selber machen und sieht dann in der Simulation, ob zwei Module 
gleichzeitig auf ein drittes Modul zugreifen wollen.

Daher verwendet man inout und Tristate-Treiber nur an den IOs.

Duke

von Knut E. (knulli)


Lesenswert?

Also DataIn und DataOut bei untergeordneten Entities verwenden, wenn ich 
die Busumschalterei nicht in der TopLevel machen will?

Knulli

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.