www.mikrocontroller.net

Forum: FPGA, VHDL & Co. FPGA mit Datenbus eines MCs verbinden


Autor: Wolfgang (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Jungens,
ich möchte folgendes machen:
auf einem Mikrocontrollerboard mit einem LPC2xxx Controller (Weiss noch 
nicht genau welchen ich verwenden möchte) soll ein FPGA mit drauf, der 
als Peripheriebaustein funktioniert.
Nach aussen wird der FPGA viele SPI-Schnittstellen haben, und mehrere 
PWM-Kanäle.
Das ansich ist auch nicht das PRoblem, sondern das folgende:
der FPGA soll beim Mikrocontroller am externen Memory Interface 
angeschlossen werden, sodass er vom Controller wie ein SRAM angesprochen 
werden kann (memory mapped I/O).

Könnt ihr mir vielleicht einen Tipp geben, wie ich die Register im FPGA 
realisieren kann und den Daten-/Adressbus, damit der Mikrocontroller 
damit zurechtkommt? Ich bin noch nicht so der Profi auf VHDL, aber ich 
will das jetzt lernen. Schematic ist nicht so dolle für solche Sachen 
;-)

Gruss Wolfgang

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Könnt ihr mir vielleicht einen Tipp geben, wie ich die Register im FPGA
> realisieren kann und den Daten-/Adressbus, damit der Mikrocontroller
> damit zurechtkommt?
Am einfachsten dürfte hier die Verwendung eines Dual-Ported-RAM sein. So 
kannst du die beiden Taktdomänen uC <-> FPGA am einfachsten entkoppeln.

> Ich bin noch nicht so der Profi auf VHDL, aber ich will das jetzt lernen.
Dann solltest du aber vorerst die Aufgabe in einzelne kleine Häppchen 
aufteilen. Mach erst mal das asynchrone Interface zum uC mit LEDs und 
Tastern. Dann machst du dir Gedanken, wie du das Ganze auf den FPGA-Takt 
einsynchronisierst und verarbeitest.

Autor: Wolfgang (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Lothar,
Wie beschreibt man denn ein solches dual port RAM in VHDL?
Ich will übrigens Quartus II von Altera verwenden, falls das eine Rolle 
spielt.

> Dann solltest du aber vorerst die Aufgabe in einzelne kleine Häppchen
> aufteilen. Mach erst mal das asynchrone Interface zum uC mit LEDs und
> Tastern. Dann machst du dir Gedanken, wie du das Ganze auf den FPGA-Takt
> einsynchronisierst und verarbeitest.

so ähnlich dachte ich mir das schon. Am besten wäre wohl ein dual port 
RAM, auf der einen seite Taster, um den uC zu simulieren, auf der 
anderen LEDs um die einzelnen Bits im RAM zu sehen. Oder?

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wie beschreibt man denn ein solches dual port RAM in VHDL?
> ...Quartus II von Altera verwenden, falls das eine Rolle spielt.
Tut es durchaus...
Wie ein DPRAM beschrieben wird, damit fertige RAM-Bausteine verwendet 
werden, ist z.B. für Xilinx im Synthesis Guide XST.pdf beschrieben. Für 
Altera dürfte es sowas ähnliches auch geben.

Autor: gonzo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie wäre es als Alternative, wenn Du den Takt für Dein FPGA aus dem Takt 
des µC beziehst? Da die Bussignale des µC höchstwahrscheinlich synchron 
zu seinem Takt sind, kannst Du Dir das Einsynchronisieren dann sparen. 
Intern kann das FPGA mit einem ganzzahligen Vielfachen des so 
vorgegebenen Takts arbeiten, wenn Du diesen schnelleren Takt per PLL aus 
dem externen Takt ableitest. Dann brauchst Du auch hier nichts zu 
synchronisieren...

Autor: Wolfgang (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi gonzo,
das Problem dabei ist, dass mein uC einen Quarzoszillator von 4 MHz hat 
und den Takt dann intern auf 72 MHz vervielfacht. Leider lässt sich 
diese vielfache Frequenz nirgends ausgeben, ich hätte hächstens 4 MHz 
zur Verfügung...

Autor: RAMZUGREIFER (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich mach das mit einem LPC2294 Controller.
Ist eigentlich ganz einfach, der LPC2294 hat ein
externes Memory-Interface und an einem Pin
kannst du den internen Takt ausgeben lassen,
der nennt sich XCLK.
Mit diesem Takte ich dann das FPGA Interface
synchron zum LPC Daten-Adressbus.

Du brauchst eigentlich nur den Datenbus,
den Adressbus, das WE (BLS Signal beim LPC2294)
und das CS.
Im LPC mußt du die Register entsprechen setzen,
und dann kannst du auf das FGPA mittels eines
Memory-Befehls lesend und schreibend zugreifen.
Den VHDL Code für das Interface ist eigentlich
auch kein Hexenwerk.


Gruß

Ralf

Autor: Wolfgang (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Ralf,
kannst du mir mal ein bisschen von deinem VHDL-Code zeigen?
Wie übernimmst du die Daten?
Ich hab intern ein Signal definiert:

signal data : std_logic_vector(7 downto 0);

und dann

process begin
  wait until rising_edge(clk);
  if we = '0' and ce = '0' and oe = '1' then
    data <= datenbus;
  end if;
  if we = '1' and ce = '0' and oe = '0' then
    datenbus <= data;
  end if;
end process;

wobei datenbus dann die 8 pins sind für 8 parallele Bits.

Autor: RAMZUGREIFER (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Hi Ralf,
>kannst du mir mal ein bisschen von deinem VHDL-Code zeigen?

Aber nur weil du es bist ;-).
Ich habe zwei prozesse. Einen für Register lesen
und einen für Register schreiben.

clk      ist xclk vom LPC2294
cs       ist cs(1) vom LPC2294
we       ist bls(0) vom LPC2294
address  ist der Datenbus vom LPC2294
datenbus ist der 8 bit breite Datenbus vom LPC2294
rst      ist eine Resetsignal, kannst du aber auch weglassen
  signal data : std_logic_vector(7 downto 0);

  process (clk, rst)          -- register schreiben
  begin
    if (rst = RESET_ACTIVE) then
       -- init something
    elsif rising_edge(clk) then
      if (cs = '0' and we = '0') then
        case address is
           when x"00" =>     -- x"00" entspricht ADR x80000000 am LPC2294
             data <= datenbus;

          when others =>
            null;
        end case;
      end if;
    end if;
  end process;


  process (clk, rst)           -- register lesen
  begin
    if (rst = RESET_ACTIVE) then
      -- init something
    elsif rising_edge(clk) then
      if (cs = '0' and we = '1') then
        case address is
          when x"00" =>    -- x"00" entspricht ADR x80000000 am LPC2294
           datenbus <= data;

         when others =>
            null;
        end case;
      end if;
    end if;
  end process;


Mehr verrate ich nicht. Den Rest mußt du schon
selbst rausfinden. Die größte Herausforderung besteht
jetzt noch darin im LPC die Register entsprechend zu
setzen.

Gruß

Ralf

Autor: RAMZUGREIFER (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ups, ich habe noch vergessen:

Im Toplevelfile teile ich
den Datenbus in Data_in
und Data_out auf, und
setze den Datenbus hochohmig
wenn oe = 0 und cs = 0 ist.
  signal data : std_logic_vector(7 downto 0);

  process (clk, rst)          -- register schreiben
  begin
    if (rst = RESET_ACTIVE) then
       -- init something
    elsif rising_edge(clk) then
      if (cs = '0' and we = '0') then
        case address is
           when x"00" =>     -- x"00" entspricht ADR x80000000 am LPC2294
             data <= data_in;

          when others =>
            null;
        end case;
      end if;
    end if;
  end process;


  process (clk, rst)           -- register lesen
  begin
    if (rst = RESET_ACTIVE) then
      -- init something
    elsif rising_edge(clk) then
      if (cs = '0' and we = '1') then
        case address is
          when x"00" =>    -- x"00" entspricht ADR x80000000 am LPC2294
           data_out <= data;

         when others =>
            null;
        end case;
      end if;
    end if;
  end process;


  -- Zuweisung Datenbus
  data    <= data_out when (oe = '0' and cs = '0') else (others => 'Z');
  data_in <= data;



Gruß

Ralf

Autor: Wolfgang (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
> Aber nur weil du es bist ;-).

cool, vielen Dank :-)

Noch ne kleine Frage.
Und zwar habe ich am FPGA auch noch ein EA DOGM128 Grafikdisplay dran, 
welches über SPI angesprochen wird. Im FPGA ist dann ein 1 kByte grosser 
Puffer, welcher das anzuzeigende Bild beinhaltet! Der FPGA gibt diesen 
Puffer über SPI dann periodisch an das Display aus.
Jetzt möchte ich eine kleine hardwaremässige Grafikunterstützung 
realisieren: schreibt der Controller in ein spezielles Command Register 
einen Opcode, z.B. für "zeichne eine Linie", dann soll der FPGA in 
diesen 1k grossen Puffer selbständig die entsprechende Linie malen. Geht 
sowas, was mir da vorschwebt?

Autor: gonzo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gehen es natürlich tut, aber kompliziert es wird. Ich mir das nicht 
antun würde... ;-)

Aber wie wäre es mit folgender einfach zu realisierender Optimierung: Da 
Du das RAM im FPGA sehr flexibel aufteilen kannst, könntest Du es dem 
Prozessor in einem zusätzlichen Adressbereich bitweise adressierbar 
präsentieren. Dann kannst Du ein Pixel durch eine einfache 
Schreiboperation setzen und sparst Dir ein Lesen und ein Odern.

Die nächste Stufe wären dann Operationen auf rechteckigen Pixelblöcken 
im FPGA (Clear, Move, Copy etc.). Das sollte auch noch einfach zu 
realisieren sein. Ob es sich aber auch lohnt, mußt Du wissen. Ich würde 
das ganz am Ende der Entwicklung angehen.

Falls Du Einfluß auf die Hardware nehmen kannst: Lege XCLK unbedingt auf 
einen Clock-Eingang des FPGA. Nur dann kannst Du die PLL-Lösung von oben 
implementieren.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.