123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310 |
- ----------------------------------------------------------------------------------
- -- Company:
- -- Engineer:
- --
- -- Create Date: 17:16:45 02/27/2018
- -- Design Name:
- -- Module Name: Magneto_Drv - Behavioral
- -- Project Name:
- -- Target Devices:
- -- Tool versions:
- -- Description:
- --
- -- Dependencies:
- --
- -- Revision:
- -- Revision 0.01 - File Created
- -- Additional Comments:
- --
- ----------------------------------------------------------------------------------
- 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 Magneto_Drv is
- Port ( I2C_FIFO_Empty : in STD_LOGIC;
- I2C_FIFO_Full : in STD_LOGIC;
- I2C_FIFO_DO : in STD_LOGIC_VECTOR (7 downto 0);
- I2C_Busy : in STD_LOGIC;
- DRDY : in STD_LOGIC;
- OutputRate : in STD_LOGIC_VECTOR (2 downto 0);
- Reset : in STD_LOGIC;
- Clk : in STD_LOGIC;
- I2C_Go : out STD_LOGIC;
- I2C_FIFO_Push : out STD_LOGIC;
- I2C_FIFO_Pop : out STD_LOGIC;
- I2C_FIFO_DI : out STD_LOGIC_VECTOR (7 downto 0);
- I2C_Addr : out STD_LOGIC_VECTOR (7 downto 0);
- I2C_ReadCnt : out STD_LOGIC_VECTOR (3 downto 0);
- ID : out STD_LOGIC_VECTOR (23 downto 0);
- DRX : out STD_LOGIC_VECTOR (15 downto 0);
- DRY : out STD_LOGIC_VECTOR (15 downto 0);
- DRZ : out STD_LOGIC_VECTOR (15 downto 0);
- DR_New : out STD_LOGIC);
- end Magneto_Drv;
-
- architecture Behavioral of Magneto_Drv is
- -- Main state machine
- type state_type is ( Init, PushAddrID, SendAddrID, BusyAddrID, ReceiveID, BusyID, ReadID, PopID, CheckID,
- PushAddrConfigA, PushDataConfigA, SendConfigA, BusyConfigA, PushAddrMode, PushDataMode,
- SendMode, BusyMode, MeasureWait, MeasureReceive, MeasureBusy, MeasureRead, MeasurePop,
- MeasureCheck, MeasureLoad, MeasureOutput, MeasurePushAddr, MeasureSendAddr, MeasureBusyAddr );
- signal state, next_state : state_type;
-
- -- DRDY synchronized input
- signal DRDY_in : STD_LOGIC;
-
- -- Input registers
- signal ID_reg : STD_LOGIC_VECTOR (23 downto 0);
- signal Input : STD_LOGIC_VECTOR (47 downto 0);
-
- -- Input byte counter
- signal bytes : integer range 0 to 5 := 0;
-
- -- Measure output registers
- signal DRX_reg : STD_LOGIC_VECTOR (15 downto 0);
- signal DRY_reg : STD_LOGIC_VECTOR (15 downto 0);
- signal DRZ_reg : STD_LOGIC_VECTOR (15 downto 0);
-
- begin
- -- DRDY input synchronization to internal clock
- sync_process : process(Clk, Reset)
- begin
- if Reset = '1' then
- DRDY_in <= '0';
- elsif rising_edge(Clk) then
- DRDY_in <= DRDY;
- end if;
- end process sync_process;
-
- -- Main HMC5883L FSM
- -- (continuos measurement)
- process1 : process(Clk)
- begin
- if rising_edge(Clk) then
- if Reset = '1' then
- state <= Init;
- else
- state <= next_state;
- end if;
- end if;
- end process process1;
-
- process2 : process(state, I2C_FIFO_Empty, I2C_Busy, DRDY_in)
- begin
- next_state <= state; -- by default
-
- case state is
- -- Initialization
- -- Reading identification register
- when Init =>
- next_state <= PushAddrID;
- when PushAddrID =>
- next_state <= SendAddrID;
- when SendAddrID =>
- next_state <= BusyAddrID;
- when BusyAddrID =>
- if I2C_Busy = '0' then
- next_state <= ReceiveID;
- end if;
- when ReceiveID =>
- next_state <= BusyID;
- when BusyID =>
- if I2C_Busy = '0' then
- next_state <= ReadID;
- end if;
- when ReadID =>
- next_state <= PopID;
- when PopID =>
- next_state <= CheckID;
- when CheckID =>
- if I2C_FIFO_Empty = '1' then
- next_state <= PushAddrConfigA;
- else
- next_state <= ReadID;
- end if;
- -- Setting data rate and mode
- when PushAddrConfigA =>
- next_state <= PushDataConfigA;
- when PushDataConfigA =>
- next_state <= SendConfigA;
- when SendConfigA =>
- next_state <= BusyConfigA;
- when BusyConfigA =>
- if I2C_Busy = '0' then
- next_state <= PushAddrMode;
- end if;
- when PushAddrMode =>
- next_state <= PushDataMode;
- when PushDataMode =>
- next_state <= SendMode;
- when SendMode =>
- next_state <= BusyMode;
- when BusyMode =>
- if I2C_Busy = '0' then
- next_state <= MeasureWait;
- end if;
- -- Measuring...
- when MeasureWait =>
- if DRDY_in = '0' then
- next_state <= MeasureReceive;
- end if;
- when MeasureReceive =>
- next_state <= MeasureBusy;
- when MeasureBusy =>
- if I2C_Busy = '0' then
- next_state <= MeasureRead;
- end if;
- -- Reading results...
- when MeasureRead =>
- next_state <= MeasurePop;
- when MeasurePop =>
- next_state <= MeasureCheck; --
- when MeasureCheck =>
- if I2C_FIFO_Empty = '1' then
- next_state <= MeasureLoad;
- else
- next_state <= MeasureRead;
- end if;
- when MeasureLoad =>
- next_state <= MeasureOutput;
- when MeasureOutput =>
- next_state <= MeasurePushAddr;
- when MeasurePushAddr =>
- next_state <= MeasureSendAddr;
- when MeasureSendAddr =>
- next_state <= MeasureBusyAddr;
- when MeasureBusyAddr =>
- if I2C_Busy = '0' then
- next_state <= MeasureWait;
- end if;
- end case;
- end process process2;
-
- id_register : process(Clk, state, next_state)
- begin
- if rising_edge(Clk) then
- if state = ReadID then
- case bytes is
- when 0 =>
- ID_reg(23 downto 16) <= I2C_FIFO_DO;
- when 1 =>
- ID_reg(15 downto 8) <= I2C_FIFO_DO;
- when 2 =>
- ID_reg(7 downto 0) <= I2C_FIFO_DO;
- when others =>
- ID_reg <= X"000000";
- end case;
- end if;
- end if;
- end process id_register;
-
- -- Storing measurements in register
- input_register : process(Clk, state, next_state)
- begin
- if rising_edge(Clk) then
- if state = MeasureRead then
- case bytes is
- when 0 =>
- Input(47 downto 40) <= I2C_FIFO_DO;
- when 1 =>
- Input(39 downto 32) <= I2C_FIFO_DO;
- when 2 =>
- Input(31 downto 24) <= I2C_FIFO_DO;
- when 3 =>
- Input(23 downto 16) <= I2C_FIFO_DO;
- when 4 =>
- Input(15 downto 8) <= I2C_FIFO_DO;
- when 5 =>
- Input(7 downto 0) <= I2C_FIFO_DO;
- end case;
- end if;
- end if;
- end process input_register;
-
- -- Stored bytes counter
- byte_counter : process(Clk)
- begin
- if rising_edge(Clk) then
- if Reset = '1' then
- bytes <= 0;
- end if;
- if state = MeasurePop then
- if bytes = 5 then
- bytes <= 0;
- else
- bytes <= bytes + 1;
- end if;
- end if;
- if state = PopID then
- if bytes = 2 then
- bytes <= 0;
- else
- bytes <= bytes + 1;
- end if;
- end if;
- end if;
- end process byte_counter;
-
- -- Buffering output in registers
- output_sync : process(Clk, state, next_state)
- begin
- if rising_edge(Clk) then
- if state = MeasureLoad then
- DRX_reg <= Input(47 downto 32);
- DRZ_reg <= Input(31 downto 16);
- DRY_reg <= Input(15 downto 0);
- end if;
- end if;
- end process output_sync;
-
- -- Output signals for FSM
- I2C_FIFO_DI <= X"0A" when next_state = PushAddrID or state = PushAddrID else
- X"00" when next_state = PushAddrConfigA or state = PushAddrConfigA else
- "000" & OutputRate & "00" when next_state = PushDataConfigA or state = PushDataConfigA else
- X"02" when next_state = PushAddrMode or state = PushAddrMode else
- X"00" when next_state = PushDataMode or state = PushDataMode else
- X"03" when next_state = MeasurePushAddr or state = MeasurePushAddr else
- X"00";
-
- I2C_FIFO_Push <= '1' when state = PushAddrID or state = PushAddrConfigA or state = PushDataConfigA
- or state = PushAddrMode or state = PushDataMode or state = MeasurePushAddr else
- '0';
-
- I2C_Addr <= X"3C" when next_state = SendAddrID or state = SendAddrID or next_state = SendConfigA
- or state = SendConfigA or next_state = SendMode or state = SendMode
- or next_state = MeasureSendAddr or state = MeasureSendAddr else
- X"3D" when next_state = ReceiveID or state = ReceiveID or next_state = MeasureReceive
- or state = MeasureReceive else
- X"00";
-
- I2C_Go <= '1' when state = SendAddrID or state = ReceiveID or state = SendConfigA or state = SendMode
- or state = MeasureReceive or state = MeasureSendAddr else
- '0';
-
- I2C_ReadCnt <= X"3" when next_state = ReceiveID or state = ReceiveID else
- X"6" when next_state = MeasureReceive or state = MeasureReceive else
- X"0";
-
- I2C_FIFO_Pop <= '1' when state = PopID or state = MeasurePop else
- '0';
-
- DR_New <= '1' when state = MeasureOutput else
- '0';
-
- -- Output registers
- ID <= ID_reg;
- DRX <= DRX_reg;
- DRY <= DRY_reg;
- DRZ <= DRZ_reg;
-
- end Behavioral;
|