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.
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
Basierend auf Ihrem (sehr unvollständigen) Schaltplan sollten Sie Folgendes verwenden:
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.
Runsiv
Runsiv
FRob
Runsiv
FRob
Runsiv
Runsiv
FRob