www.mikrocontroller.net

Forum: FPGA, VHDL & Co. NIOS II mit eigenem Bauteil verbinden


Autor: Peer Ruudje (moepser)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich bin neu im Forum, natürlich habe ich die Suchfunktion bedient, aber 
keine passende Hilfe bekommen. Sollte ich einen passenden Beitrag 
übersehen oder nicht gefunden haben, bitte ich das zu entschuldigen.
Zu meinem Problem:
Ich möchte einen bestehenden NIOS2 Prozessor um eine eigene Komponente 
erweitern. Bei der Komponente soll es sich um einen simplen Counter mit 
preload handeln. Sprich, es soll einen 8 Bit breiten eingang geben, dem 
ein Wert übergeben werden kann, von dem aus dann der Zähler bis 255 
hochzählt. Für den Fall das nichts übergeben wird, soll einfach bei 0 
angefangen werden. Weiter soll der Zähler erst anfangen zu zählen, wenn 
er ein Start-Bit gesetzt wird. Natürlich soll es auch einen Reset und 
CLK Eingang geben.

Ich habe ein Bauteil erstellt:
library IEEE;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity CounterWPreload is
  port (
      -- <interface type>_<interface name>_<signal type>
      avs_avalonslave_writedata:  IN std_logic_vector (7 downto 0);
      avs_avalonslave2_writedata: IN std_logic;
      avs_avalonslave_write:    IN std_logic;
      csi_clockreset_clk:      IN std_logic;
      csi_clockreset_reset:    IN std_logic;
      coe_counterOutput_export:  OUT std_logic_vector (7 downto 0)
      );
end CounterWPreload;

architecture CounterWPreload_arch of CounterWPreload is
signal counter:   std_logic_vector (7 downto 0); -- enthaellt zaehlerstand
signal stop:    std_logic := '0';  -- signalisiert, dass der zahler voll ist

begin
standart: process (csi_clockreset_clk, csi_clockreset_reset)
begin
  if (csi_clockreset_reset = '1') then        --wurde der Reset gesetzt
    counter <= avs_avalonslave_writedata;    --setze den counter zurueck auf den Wert des Preload
    stop <= '0';            --setze das Stopbit auf 0
  elsif(csi_clockreset_clk'event and csi_clockreset_clk = '1' and stop = '0' and avs_avalonslave2_writedata = '1') then -- wenn der Takt eintrifft und der Baustein aktiv ist und der Zaehler nicht durchgelaufen ist
    if(avs_avalonslave_write = '1') then
      counter <= avs_avalonslave_writedata;
    elsif (avs_avalonslave_write = '0') then
      coe_counterOutput_export <= counter;    -- dann gebe den momentanen counterstand aus
      counter <= counter + 1;      -- und erhoehe den counterstand
      if(counter = "11111111") then -- ist der zaehler vollgelaufen
        stop <= '1';          -- dann aktiviere das stopbit
      end if;
    end if;
  end if;
end process;

end CounterWPreload_arch;

Mein Problem ist nun, wenn ich das Bauteil über den SoPC Builder in den 
NIOS2 einbinde, dann weiß ich nicht wie es an den Avalon Master 
angebunden wird, sprich: Wie schaffe ich es, dass ein Bit verwendet 
werden kann um den Zähler loslaufen zu lassen? Und wie kann ich in C 
dann dieses Bit setzen und Daten an den Zähler schicken um ihn zu laden? 
Ich habe diese Funktion in Forenbeiträgen gefunden: 
IOWR_8DIRECT(COUNTER_W_PRELOAD_8BIT_0_BASE, 0, 0xAA);
aber die führt bei mir nur zu Fehlern.

Kann mir jemand helfen? Vielen Dank!

Autor: Kest (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lies mal die Doku zum AVALON-Interface -- das was Du gemacht hast ist 
falsch.
1. clk'event und clk='1' ist nur für getaktete Prozesse gedacht, also da 
sollten keine weitere "and stop = '0' and avs_avalonslave2_writedata = 
'1'" auftauchen
2. ein AVALON Interface besteht aus writedata, write, adress (vielleicht 
noch chip_select und wait_request)
D.h. in Deiner Komponente müsstest Du ein Register-Set aufbauen, etwa 
so:

if avalon_write = '1' then
  if avalon_adress = x"00" then
     internal_counter <= write_data
  end if;
end if;

Das ist nur pseudocode. Such' mal hier im Forum danach, das habe ich 
schon ein Paar mal beschreiben.

Am besten Du liest die Doku, damit Du es auch verstehst, was Du machst. 
Viel Erfolg,

Kest

Autor: Peer Ruudje (moepser)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi, danke für die schnelle Antwort!

Ich gebe zu ich bin weder mit VHDL noch mit dem NIOS oder Quartus sehr 
vertraut. Ich habe mir die Avalon Spezifikation (teilweise) 
durchgelesen.

Habe ich das richtig verstanden, würde man eine Variable namens:
avs_avalonslave_address: IN std_logic
 erstellen, kann man über diese die Datenbytes der Komponente auswählen? 
Also würde ich in meinen Fall (siehe oben) mit avs_avalonslave_address = 
'0' die ersten 8 Bit meiner Komponente zum beschreiben auswählen? Aber 
wenn das so ist, woher weiß ich, welche die ersten 8 Bits sind? Bzw. 
wenn ich davon ausgehe, dass über writedata die beschreibaren Bits 
ausgewählt werden, wie kann ich dann noch register hinzufügen, die 
unabhängig von den writedata beschrieben werden? Oder muss ich die größe 
des writedata verändern und dann über avs_avalonslave_address = '1' die 
nächsten 8 Bis auswählen?

Bitte habt Gedult mit einem Neuling, lasst mich nicht dumm sterben! ;)

Vielen Dank!

Autor: Kest (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
Ein Avalon-Slave sieht in etwa so aus:

entity digital_io is

  port (
    -- Avalon Clock
    clk_m : in std_logic;

    -- AVALON Slave Interface
    as_address       : in  std_logic_vector(7 downto 0);
    as_chipselect    : in  std_logic;
    as_read          : in  std_logic;
    as_write         : in  std_logic;
    as_writedata     : in  std_logic_vector(31 downto 0);
    as_readdata      : out std_logic_vector(31 downto 0);
    as_readdatavalid : out std_logic;
    as_waitrequest   : out std_logic;

    -- externe Pins
    ....

    );

end digital_io;


und später irgendwo:

  ------------------------------------------------------------------------ 
-----
  -- AVALON Slave Interface / Registerset
  ------------------------------------------------------------------------ 
-----
  as_readdata    <= reg_readdata;
  as_waitrequest <= not (as_write or as_read);

  process(clk_m)
  begin
    if rising_edge(clk_m) then

      ------------------------------------------------------------------------ 
-
      -- SCHREIBEN
      ------------------------------------------------------------------------ 
-
      if as_chipselect = '1' and as_write = '1' then
        case as_address is
          when x"00" => cpld_spi_clock_div <= unsigned(as_writedata(7 
downto 0));
          when x"01" => max_cpld_cnt <= 
unsigned(as_writedata(max_cpld_cnt'range));
          when x"02" => Output_Register <= as_writedata;
          when x"03" => digital_o_reg   <= as_writedata;

          when others => null;
        end case;
      end if;
      ------------------------------------------------------------------------ 
-
      -- LESEN
      ------------------------------------------------------------------------ 
-
      as_readdatavalid <= as_chipselect and as_read;

      if as_chipselect = '1' and as_read = '1' then
        case as_address is
          when x"00"  => reg_readdata <= Input_register(31 downto 0);
          when x"01"  => reg_readdata  <= digital_i_reg;
          when x"02"  => reg_readdata(15 downto 0) <= cBOARD_REVISION;
          when others => null;
        end case;
      end if;

    end if;
  end process;

das Ganze ist eher exemplarisch und nicht vollständig. Aber es sollte 
klar sein, wie es funktioniert.

Grüße,
Kest

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.