Projekt z kursu Układy cyfrowe i systemy wbudowane 2 na PWr
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

Magneto_Drv.vhd 9.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. ----------------------------------------------------------------------------------
  2. -- Company:
  3. -- Engineer:
  4. --
  5. -- Create Date: 17:16:45 02/27/2018
  6. -- Design Name:
  7. -- Module Name: Magneto_Drv - Behavioral
  8. -- Project Name:
  9. -- Target Devices:
  10. -- Tool versions:
  11. -- Description:
  12. --
  13. -- Dependencies:
  14. --
  15. -- Revision:
  16. -- Revision 0.01 - File Created
  17. -- Additional Comments:
  18. --
  19. ----------------------------------------------------------------------------------
  20. library IEEE;
  21. use IEEE.STD_LOGIC_1164.ALL;
  22. -- Uncomment the following library declaration if using
  23. -- arithmetic functions with Signed or Unsigned values
  24. use IEEE.NUMERIC_STD.ALL;
  25. -- Uncomment the following library declaration if instantiating
  26. -- any Xilinx primitives in this code.
  27. --library UNISIM;
  28. --use UNISIM.VComponents.all;
  29. entity Magneto_Drv is
  30. Port ( I2C_FIFO_Empty : in STD_LOGIC;
  31. I2C_FIFO_Full : in STD_LOGIC;
  32. I2C_FIFO_DO : in STD_LOGIC_VECTOR (7 downto 0);
  33. I2C_Busy : in STD_LOGIC;
  34. DRDY : in STD_LOGIC;
  35. OutputRate : in STD_LOGIC_VECTOR (2 downto 0);
  36. Reset : in STD_LOGIC;
  37. Clk : in STD_LOGIC;
  38. I2C_Go : out STD_LOGIC;
  39. I2C_FIFO_Push : out STD_LOGIC;
  40. I2C_FIFO_Pop : out STD_LOGIC;
  41. I2C_FIFO_DI : out STD_LOGIC_VECTOR (7 downto 0);
  42. I2C_Addr : out STD_LOGIC_VECTOR (7 downto 0);
  43. I2C_ReadCnt : out STD_LOGIC_VECTOR (3 downto 0);
  44. ID : out STD_LOGIC_VECTOR (23 downto 0);
  45. DRX : out STD_LOGIC_VECTOR (15 downto 0);
  46. DRY : out STD_LOGIC_VECTOR (15 downto 0);
  47. DRZ : out STD_LOGIC_VECTOR (15 downto 0);
  48. DR_New : out STD_LOGIC);
  49. end Magneto_Drv;
  50. architecture Behavioral of Magneto_Drv is
  51. -- Main state machine
  52. type state_type is ( Init, PushAddrID, SendAddrID, BusyAddrID, ReceiveID, BusyID, ReadID, PopID, CheckID,
  53. PushAddrConfigA, PushDataConfigA, SendConfigA, BusyConfigA, PushAddrMode, PushDataMode,
  54. SendMode, BusyMode, MeasureWait, MeasureReceive, MeasureBusy, MeasureRead, MeasurePop,
  55. MeasureCheck, MeasureLoad, MeasureOutput, MeasurePushAddr, MeasureSendAddr, MeasureBusyAddr );
  56. signal state, next_state : state_type;
  57. -- DRDY synchronized input
  58. signal DRDY_in : STD_LOGIC;
  59. -- Input registers
  60. signal ID_reg : STD_LOGIC_VECTOR (23 downto 0);
  61. signal Input : STD_LOGIC_VECTOR (47 downto 0);
  62. -- Input byte counter
  63. signal bytes : integer range 0 to 5 := 0;
  64. -- Measure output registers
  65. signal DRX_reg : STD_LOGIC_VECTOR (15 downto 0);
  66. signal DRY_reg : STD_LOGIC_VECTOR (15 downto 0);
  67. signal DRZ_reg : STD_LOGIC_VECTOR (15 downto 0);
  68. begin
  69. -- DRDY input synchronization to internal clock
  70. sync_process : process(Clk, Reset)
  71. begin
  72. if Reset = '1' then
  73. DRDY_in <= '0';
  74. elsif rising_edge(Clk) then
  75. DRDY_in <= DRDY;
  76. end if;
  77. end process sync_process;
  78. -- Main HMC5883L FSM
  79. -- (continuos measurement)
  80. process1 : process(Clk)
  81. begin
  82. if rising_edge(Clk) then
  83. if Reset = '1' then
  84. state <= Init;
  85. else
  86. state <= next_state;
  87. end if;
  88. end if;
  89. end process process1;
  90. process2 : process(state, I2C_FIFO_Empty, I2C_Busy, DRDY_in)
  91. begin
  92. next_state <= state; -- by default
  93. case state is
  94. -- Initialization
  95. -- Reading identification register
  96. when Init =>
  97. next_state <= PushAddrID;
  98. when PushAddrID =>
  99. next_state <= SendAddrID;
  100. when SendAddrID =>
  101. next_state <= BusyAddrID;
  102. when BusyAddrID =>
  103. if I2C_Busy = '0' then
  104. next_state <= ReceiveID;
  105. end if;
  106. when ReceiveID =>
  107. next_state <= BusyID;
  108. when BusyID =>
  109. if I2C_Busy = '0' then
  110. next_state <= ReadID;
  111. end if;
  112. when ReadID =>
  113. next_state <= PopID;
  114. when PopID =>
  115. next_state <= CheckID;
  116. when CheckID =>
  117. if I2C_FIFO_Empty = '1' then
  118. next_state <= PushAddrConfigA;
  119. else
  120. next_state <= ReadID;
  121. end if;
  122. -- Setting data rate and mode
  123. when PushAddrConfigA =>
  124. next_state <= PushDataConfigA;
  125. when PushDataConfigA =>
  126. next_state <= SendConfigA;
  127. when SendConfigA =>
  128. next_state <= BusyConfigA;
  129. when BusyConfigA =>
  130. if I2C_Busy = '0' then
  131. next_state <= PushAddrMode;
  132. end if;
  133. when PushAddrMode =>
  134. next_state <= PushDataMode;
  135. when PushDataMode =>
  136. next_state <= SendMode;
  137. when SendMode =>
  138. next_state <= BusyMode;
  139. when BusyMode =>
  140. if I2C_Busy = '0' then
  141. next_state <= MeasureWait;
  142. end if;
  143. -- Measuring...
  144. when MeasureWait =>
  145. if DRDY_in = '0' then
  146. next_state <= MeasureReceive;
  147. end if;
  148. when MeasureReceive =>
  149. next_state <= MeasureBusy;
  150. when MeasureBusy =>
  151. if I2C_Busy = '0' then
  152. next_state <= MeasureRead;
  153. end if;
  154. -- Reading results...
  155. when MeasureRead =>
  156. next_state <= MeasurePop;
  157. when MeasurePop =>
  158. next_state <= MeasureCheck; --
  159. when MeasureCheck =>
  160. if I2C_FIFO_Empty = '1' then
  161. next_state <= MeasureLoad;
  162. else
  163. next_state <= MeasureRead;
  164. end if;
  165. when MeasureLoad =>
  166. next_state <= MeasureOutput;
  167. when MeasureOutput =>
  168. next_state <= MeasurePushAddr;
  169. when MeasurePushAddr =>
  170. next_state <= MeasureSendAddr;
  171. when MeasureSendAddr =>
  172. next_state <= MeasureBusyAddr;
  173. when MeasureBusyAddr =>
  174. if I2C_Busy = '0' then
  175. next_state <= MeasureWait;
  176. end if;
  177. end case;
  178. end process process2;
  179. id_register : process(Clk, state, next_state)
  180. begin
  181. if rising_edge(Clk) then
  182. if state = ReadID then
  183. case bytes is
  184. when 0 =>
  185. ID_reg(23 downto 16) <= I2C_FIFO_DO;
  186. when 1 =>
  187. ID_reg(15 downto 8) <= I2C_FIFO_DO;
  188. when 2 =>
  189. ID_reg(7 downto 0) <= I2C_FIFO_DO;
  190. when others =>
  191. ID_reg <= X"000000";
  192. end case;
  193. end if;
  194. end if;
  195. end process id_register;
  196. -- Storing measurements in register
  197. input_register : process(Clk, state, next_state)
  198. begin
  199. if rising_edge(Clk) then
  200. if state = MeasureRead then
  201. case bytes is
  202. when 0 =>
  203. Input(47 downto 40) <= I2C_FIFO_DO;
  204. when 1 =>
  205. Input(39 downto 32) <= I2C_FIFO_DO;
  206. when 2 =>
  207. Input(31 downto 24) <= I2C_FIFO_DO;
  208. when 3 =>
  209. Input(23 downto 16) <= I2C_FIFO_DO;
  210. when 4 =>
  211. Input(15 downto 8) <= I2C_FIFO_DO;
  212. when 5 =>
  213. Input(7 downto 0) <= I2C_FIFO_DO;
  214. end case;
  215. end if;
  216. end if;
  217. end process input_register;
  218. -- Stored bytes counter
  219. byte_counter : process(Clk)
  220. begin
  221. if rising_edge(Clk) then
  222. if Reset = '1' then
  223. bytes <= 0;
  224. end if;
  225. if state = MeasurePop then
  226. if bytes = 5 then
  227. bytes <= 0;
  228. else
  229. bytes <= bytes + 1;
  230. end if;
  231. end if;
  232. if state = PopID then
  233. if bytes = 2 then
  234. bytes <= 0;
  235. else
  236. bytes <= bytes + 1;
  237. end if;
  238. end if;
  239. end if;
  240. end process byte_counter;
  241. -- Buffering output in registers
  242. output_sync : process(Clk, state, next_state)
  243. begin
  244. if rising_edge(Clk) then
  245. if state = MeasureLoad then
  246. DRX_reg <= Input(47 downto 32);
  247. DRZ_reg <= Input(31 downto 16);
  248. DRY_reg <= Input(15 downto 0);
  249. end if;
  250. end if;
  251. end process output_sync;
  252. -- Output signals for FSM
  253. I2C_FIFO_DI <= X"0A" when next_state = PushAddrID or state = PushAddrID else
  254. X"00" when next_state = PushAddrConfigA or state = PushAddrConfigA else
  255. "000" & OutputRate & "00" when next_state = PushDataConfigA or state = PushDataConfigA else
  256. X"02" when next_state = PushAddrMode or state = PushAddrMode else
  257. X"00" when next_state = PushDataMode or state = PushDataMode else
  258. X"03" when next_state = MeasurePushAddr or state = MeasurePushAddr else
  259. X"00";
  260. I2C_FIFO_Push <= '1' when state = PushAddrID or state = PushAddrConfigA or state = PushDataConfigA
  261. or state = PushAddrMode or state = PushDataMode or state = MeasurePushAddr else
  262. '0';
  263. I2C_Addr <= X"3C" when next_state = SendAddrID or state = SendAddrID or next_state = SendConfigA
  264. or state = SendConfigA or next_state = SendMode or state = SendMode
  265. or next_state = MeasureSendAddr or state = MeasureSendAddr else
  266. X"3D" when next_state = ReceiveID or state = ReceiveID or next_state = MeasureReceive
  267. or state = MeasureReceive else
  268. X"00";
  269. I2C_Go <= '1' when state = SendAddrID or state = ReceiveID or state = SendConfigA or state = SendMode
  270. or state = MeasureReceive or state = MeasureSendAddr else
  271. '0';
  272. I2C_ReadCnt <= X"3" when next_state = ReceiveID or state = ReceiveID else
  273. X"6" when next_state = MeasureReceive or state = MeasureReceive else
  274. X"0";
  275. I2C_FIFO_Pop <= '1' when state = PopID or state = MeasurePop else
  276. '0';
  277. DR_New <= '1' when state = MeasureOutput else
  278. '0';
  279. -- Output registers
  280. ID <= ID_reg;
  281. DRX <= DRX_reg;
  282. DRY <= DRY_reg;
  283. DRZ <= DRZ_reg;
  284. end Behavioral;