www.mikrocontroller.net

Forum: FPGA, VHDL & Co. Datenregister im FPGA


Autor: Tobias Plüss (hubertus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich habe nun zum ersten mal auf einem selber gebauten Board einen FPGA 
und uC miteinander verbunden via 8 Bit breiten Daten- und Adressbus.
Und soweit funktioniert alles perfekt!
Nun habe ich aber ein paar fragen.

Grundsätzlich: der uC führt das interne CPU-Taktsignal nach aussen, und 
dieses ist mit dem FPGA verbunden. Alle Signale vom uC sind zu diesem 
Taktsignal synchron, weshalb ich mir dachte, dass ich die 
Einsynchronisierung der einzelnen Signale sparen kann (was ich hier im 
Forum gelesen habe - anscheinend ist das zulässig).

So, ich habe im FPGA nun verschiedene "Register", auf die der uC 
zugreifen kann, wo bestimmte Daten gelesen oder geschrieben werden.

Mit folgendem Code wird dies realisiert:
signal q : std_logic_vector(7 downto 0);
signal register1 : std_logic_vector(7 downto 0);
signal register2 : std_logic_vector(7 downto 0);

process begin --write
  wait until falling_edge(clk);
  if ce = '0' and oe = '1' and we = '0' then
    if adressbus = 0 then
      register1 <= datenbus;
    elsif adressbus = 1 then
      register2 <= datenbus;
    end if;
  end if;
end process;

process begin --read
  wait until falling_edge(clk);
  if ce = '0' and oe = '0' and we = '1' then
    if adressbus = 0 then
      q <= register1;
    elsif adressbus = 1 then
      q <= register2;
    else
      q <= (others => '0');
    end if;
  end if;
end process;

datenbus <= q when ce = '0' and oe = '0' and we = '1' else (others => 'Z');

so könnte man das beliebig weiter stricken und für jedes Register eine 
if-Abfrage machen. Das gefällt mir aber nicht so recht; geht das auch 
irgendwie eleganter?

dann, die nächste Frage. Ich habe in einem Register die Bits INTEN, 
SWINT, IRQF, SRST und TST. Jedes der Bits ist in Wirklichkeit natürlich 
ein Signal im FPGA, womit sich dann irgendwelche Dinge ein-, aus- oder 
umschalten lassen. Was ist besser:
process begin --write
  wait until falling_edge(clk);
  if ce = '0' and oe = '1' and we = '0' then
    if adressbus = 3 then
      INTEN <= datenbus(0);
      SWINT <= datenbus(1);
      IRQF <= datenbus(2);
      SRST <= datenbus(3);
      TST <= datenbus(4);
    end if;
  end if;
end process;

process begin --read
  wait until falling_edge(clk);
  if ce = '0' and oe = '0' and we = '1' then
    if adressbus = 3 then
      q <= "000" & TST & SRST & IRQF & SWINT & INTEN;
    else
      q <= (others => '0');
    end if;
  end if;
end process;

oder das:
process begin --write
  wait until falling_edge(clk);
  if ce = '0' and oe = '1' and we = '0' then
    if adressbus = 3 then
      testregister <= datenbus;
    end if;
  end if;
end process;

process begin --read
  wait until falling_edge(clk);
  if ce = '0' and oe = '0' and we = '1' then
    if adressbus = 3 then
      q <= testregister;
    else
      q <= (others => '0');
    end if;
  end if;
end process;

INTEN <= testregister(0);
SWINT <= testregister(1);
IRQF <= testregister(2);
SRST <= testregister(3);
TST <= testregister(4);

Funktionieren tut, gemäss meinen Experimenten, beides. Aber ich bin 
sicher, wenn es funktioniert, muss es noch nicht unbedingt gut sein :-)

Ich bin gespannt auf eure Posts.

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

Bewertung
0 lesenswert
nicht lesenswert
Tobias Plüss schrieb:
> Alle Signale vom uC sind zu diesem Taktsignal synchron,
Es kommt dann nur noch darauf an, welche Flanke relevant ist. Aber du 
hast offenbar die fallende Flanke als geeigneter gefunden...

> geht das auch irgendwie eleganter?
Nicht unbedingt, aber du kannst dir das Registrieren des Ausgangs q 
sparen und das Tristaten des Datenbusses dort gleich mit reinnehmen:
process (ce,oe,we,adressbus,register1,register2) --read
  datenbus <=  (others => 'Z');    -- default hochohmig
  if ce = '0' and oe = '0' and we = '1' then
    datenbus  <= (others => '0');  -- wenn selektiert: default "000"
    if adressbus = 0 then
        datenbus  <= register1;
    elsif adressbus = 1 then
        datenbus  <= register2;
    end if;
  end if;
end process;
Und wenn das Ganze dann sowieso kombinatorisch ist geht es auch so:
  datenbus <=  register1 when ce='0' and oe='0' and we='1' and adressbus=0 else
               register2 when ce='0' and oe='0' and we='1' and adressbus=1 else               
               (others => '0') when ce='0' and oe='0' and we='1'  else
               (others => 'Z');    -- default hochohmig

Mit einem Hilfssignal (z.B. rd) liest es sich dann leichter:
  rd <= '1' when ce='0' and oe='0' and we='1' else '0';
  datenbus <=  register1       when rd='1' and adressbus=0 else
               register2       when rd='1' and adressbus=1 else      
               (others => '0') when rd='1'  else
               (others => 'Z');    -- default hochohmig

> Was ist besser:
Das ist schlichtweg egal. Besser ist das, was du nach 1 Jahr noch ohne 
Aufwand kapierst... ;-)
Alternativ könntest du auf den Ressourcenverbrauch schauen, aber der 
dürfte sich nicht signifikant unterscheiden.

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.