VHDL SPI Xilinx Spartan 3E

Ich habe fast keine Erfahrung mit VHDL und den größten Teil des Codes hier bekomme ich vom Lehrer.

Ich versuche, mit einem ADXL362-Beschleunigungsmesser über SPI auf einem Xilinx Sparten 3E zu kommunizieren. Soweit ich aus dem RTL-Schema des ADXL362 verstehen kann, muss ich ein Modul mit 5 (?) Ports herstellen. MISO, MOSI, SS (Slave Select), Daten bereit und Systemtakt für das obere Modul, um damit zu sprechen.

Die SPI-Schnittstelle verhält sich wie ein Submodul des ADXL362-Moduls, also wie viel muss ich dann von den Ports in meinem Top-Modul deklarieren?

So wie es aussieht, ist der ADXL der Slave und ich muss ein Master-Modul schreiben, um mit ihm sprechen zu können. Aber alle Beispiele, die ich gesehen habe, haben einfach viel mehr Drähte als das, was ich im vorgefertigten Code bekommen habe. Also ich bin ab jetzt total festgefahren, also wäre jede Hilfe sehr dankbar.

Abbildung 1

Top-Modulcode:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity top_module is

    port(
        sysclk :in std_logic;

        --uart_tx: out std_logic;
        btn : in  STD_LOGIC_VECTOR (3 downto 0);
        --miso : in STD_LOGIC;
        tx : out std_logic;

        led1 : out std_logic;
        led2 : out std_logic        

        );

end top_module;

architecture Behavioral of top_module is

signal tempX : std_logic_vector (11 downto 0);
signal tempY : std_logic_vector (11 downto 0);
signal tempZ : std_logic_vector (11 downto 0);
signal ZZ : std_logic_vector (7 downto 0);
signal YY : std_logic_vector (7 downto 0);
signal XX : std_logic_vector (7 downto 0);

signal clr: std_logic;



component ADXL362Ctrl
port
(
   SYSCLK     : in STD_LOGIC; -- System Clock
   RESET      : in STD_LOGIC;

   -- Accelerometer data signals
   ACCEL_X    : out STD_LOGIC_VECTOR (11 downto 0);
   ACCEL_Y    : out STD_LOGIC_VECTOR (11 downto 0);
   ACCEL_Z    : out STD_LOGIC_VECTOR (11 downto 0);

   --SPI Interface Signals
   SCLK       : out STD_LOGIC;
    MOSI       : out STD_LOGIC;
    MISO       : in STD_LOGIC;
    SS         : out STD_LOGIC

);
end component;

);
end component;

-- convert data from 12 to 8 bit
component convertion is
port (
   ACCEL_X    : in STD_LOGIC_VECTOR (11 downto 0);
   ACCEL_Y    : in STD_LOGIC_VECTOR (11 downto 0);
   ACCEL_Z    : in STD_LOGIC_VECTOR (11 downto 0);

    Ax : out std_logic_vector (7 downto 0);
    Ay : out std_logic_vector (7 downto 0);
    Az : out std_logic_vector (7 downto 0)
    );
end component;

begin
    A : ADXL362Ctrl
--clr <= btn(3);
        port map
        (
            MISO => miso,
            SYSCLK => sysclk,
            RESET => btn(3),

            ACCEL_X => tempX,
            ACCEL_Y => tempY,
            ACCEL_Z => tempZ,                       
            --SPI Interface Signals
            SCLK        => sclk,
            MOSI        => mosi,
            MISO        => miso,
            SS          => ss
        );





    A3: convertion
        port map
            (
            Ay => YY,
            Az => ZZ,
            Ax => XX,
            ACCEL_X => tempX,
            ACCEL_Y => tempY,
            ACCEL_Z => tempZ
            );`

SPI-Schnittstelle http://pastebin.com/t7LFnvDp ADXL-Code http://pastebin.com/uwZ8mZBH

Antworten (1)

Basierend auf Ihrem (sehr unvollständigen) Schaltplan sollten Sie Folgendes verwenden:

  • ein SPI-Master
  • ein Controller für den ADXL362, der mit dem SPI-Master spricht
  • Der Controller liest die Beschleunigung (X, Y, Z) und die Temperatur (TMP), führt die notwendige Konvertierung durch und hat die konvertierte Beschleunigung und Temperatur an seinen Ausgängen zusammen mit einem data_ready-Signal, das gültige Ausgangsdaten anzeigt.

Sie haben bereits VHDL-Code für den SPI-Master und den ADXL362-Controller. Bevor Sie fortfahren, lesen Sie die Betriebstheorie beider HDL-Dateien (Kommentare oben) sowie das ADXL362-Datenblatt .

Sie müssen den ADXL362-Controller instanziieren und seine Ausgänge verwenden:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity top_module is
    Generic (
        SYSCLK_FREQUENCY_HZ : integer := 100000000 ------- Change this to your actual frequency!
    );
    Port (
        --! System Clock
        SYSCLK : in std_logic;
        --! Buttons
        BTN    : in std_logic_vector(3 downto 0);
        --! LEDs
        LED    : out std_logic_vector(1 downto 0);
        --! SPI Signals
        SCLK   : out std_logic;
        MISO   : in  std_logic;
        MOSI   : out std_logic;
        SS_N   : out std_logic
    );
end entity top_module;

architecture Behavioral of top_module is

-----------------------------------------------------------------------
-- Components
-----------------------------------------------------------------------

component ADXL362Ctrl
    Generic (
        SYSCLK_FREQUENCY_HZ : integer := 100000000;
        SCLK_FREQUENCY_HZ   : integer := 1000000;
        NUM_READS_AVG       : integer := 16;
        UPDATE_FREQUENCY_HZ : integer := 1000
    );
    Port (
        SYSCLK      : in std_logic; -- System Clock
        RESET       : in std_logic;

        -- Accelerometer data signals
        ACCEL_X     : out std_logic_vector(11 downto 0);
        ACCEL_Y     : out std_logic_vector(11 downto 0);
        ACCEL_Z     : out std_logic_vector(11 downto 0);
        ACCEL_TMP   : out std_logic_vector(11 downto 0);
        Data_Ready  : out std_logic;

        --SPI Interface Signals
        SCLK        : out std_logic;
        MOSI        : out std_logic;
        MISO        : in  std_logic;
        SS          : out std_logic
    );
end component ADXL362Ctrl;

-----------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------

signal reset     : std_logic_vector(15 downto 0) := (others => '1');

signal ss        : std_logic;
signal accel_x   : std_logic_vector(11 downto 0);
signal accel_y   : std_logic_vector(11 downto 0);
signal accel_z   : std_logic_vector(11 downto 0);
signal accel_tmp : std_logic_vector(11 downto 0);
signal drdy      : std_logic;

begin

-- ADXL362 has low-active CS (SS_N)
-- SPI Master has high-active ss => invert
SS_N <= not ss;

reset_p : process (
    SYSCLK
    )
begin

    if (rising_edge(SYSCLK)) then

        reset <= reset(reset'left - 1 downto 0) & "0";

    end if;

end process reset_p;

led_p : process (
    SYSCLK
    )
begin

    if (rising_edge(SYSCLK)) then

        if (reset(reset'left) = '1') then

            LED <= (others => '0');

        elsif (drdy = '1') then

            -- accelerations are in two's complement
            -- put sign bit onto LEDs for testing
            LED(0) <= accel_x(accel_x'left);
            LED(1) <= accel_y(accel_y'left);

        end if;

    end if;

end process led_p;

-----------------------------------------------------------------------
-- Instances
-----------------------------------------------------------------------

ADXL362Ctrl_Inst : component ADXL362Ctrl
    Generic Map (
        SYSCLK_FREQUENCY_HZ => SYSCLK_FREQUENCY_HZ,
        SCLK_FREQUENCY_HZ   => 1000000,
        NUM_READS_AVG       => 16,
        UPDATE_FREQUENCY_HZ => 1000
    )
    Port Map (
        SYSCLK      => SYSCLK,
        RESET       => reset(reset'left),

        -- Accelerometer data signals
        ACCEL_X     => accel_x,
        ACCEL_Y     => accel_y,
        ACCEL_Z     => accel_z,
        ACCEL_TMP   => accel_tmp,
        Data_Ready  => drdy,

        --SPI Interface Signals
        SCLK        => SCLK,
        MOSI        => MOSI,
        MISO        => MISO,
        SS          => ss
    );
end architecture Behavioral;

Dies ist ein Minimalbeispiel. Es instanziiert einen ADXL362Ctrl, setzt ihn ordnungsgemäß für 16 Taktzyklen zurück und lässt – abhängig von accel_x und accel_y – die LEDs anzeigen, ob Sie eine negative oder positive Beschleunigung auf der X- und Y-Achse haben.

Vergessen Sie nicht, Ihre Pins in der UCF-Datei mit geeigneten Einschränkungen zu LOC. Sie können Ihr Entwicklungsboard beschädigen, wenn Sie dies nicht tun!

Abhängig von Ihrem LED-Setup müssen Sie möglicherweise den LED-Ausgang in led_p invertieren. Ein Digital Clock Manager (DCM) wäre angebracht, aber ich fürchte, das Hinzufügen eines hier würde Sie nur noch mehr verwirren. Ihr Lehrer oder Lehrassistent kann Ihnen sagen, wie Sie ein DCM richtig instanziieren.

Vielen Dank. Endlich habe ich eine klare Vorstellung davon, was ich zu tun habe. Mein anderes Gruppenmitglied hat gesagt, dass es nicht nötig sei, irgendetwas zu tun, der Spi und der Lehrer seien nicht verfügbar.
Ich bin auf ein kleines Problem gestoßen. "SYSCLK_FREQUENCY_HZ => SYSCLK_FREQUENCY_HZ" gibt mir einen Fehler, ein undefiniertes Symbol, wenn ich ihm keinen numerischen Wert gebe. Und ich verstehe nicht warum, da es definiert ist.
Welches Synthesetool verwendest du? Bei einigen müssen Sie Generics der obersten Ebene explizit in den Optionen definieren. Wenn Sie es also nicht in den Optionen definieren, wird der Standardwert nicht verwendet und das Generikum wäre undefiniert.
Ich verwende das XST von ISE 14.7.
Nun, das XST von ISE sollte "einfach funktionieren". Ich habe gerade bestätigt, dass dies in einem Dummy-Projekt funktioniert. Sind Sie sicher, dass Sie nicht vergessen haben, das Generikum zu Ihrer Toplevel-Entität hinzuzufügen? Bitte poste mal die eigentliche Fehlermeldung. Ohne eine tatsächliche Nachricht kann ich wenig tun. Stellen Sie sicher, dass die Teile, die Sie für Ihr Design hinzugefügt haben, keine Syntaxfehler enthalten.
Sie hatten Recht, ich hatte vergessen, es der Entität der obersten Ebene hinzuzufügen. Vielen Dank für all die Hilfe.
Ich versuche, die Beschleunigungsmesserdaten in eine Konverterfunktion zu analysieren, die sie in ein 8-Bit-Signal umwandelt, aber die Drähte verbinden sich nicht. Mein Code: XX, YY, ZZ sind die Eingänge für einen VGA-Bildschirm. Ist das der völlig falsche Weg? Code
Möglicherweise erhalten Sie bessere Hilfe, wenn Sie eine weitere Frage mit dem entsprechenden Code und insbesondere der wörtlichen Fehlermeldungszeichenfolge posten. Niemand kann dir helfen, wenn du nicht genug Details zeigst.