Various projects using Raspberry Pi
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

215 lines
6.2 KiB

  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. use ieee.numeric_std.all;
  4. entity FiRoCtrlE is
  5. generic (
  6. EXTRACT : boolean := true
  7. );
  8. port (
  9. --+ system if
  10. Clk_i : in std_logic;
  11. Reset_i : in std_logic;
  12. --+ ctrl/status
  13. Start_i : in std_logic;
  14. Wait_i : in std_logic_vector(7 downto 0);
  15. Run_i : in std_logic_vector(7 downto 0);
  16. --+ rnd data
  17. DataValid_o : out std_logic;
  18. Data_o : out std_logic_vector(7 downto 0);
  19. -- firo
  20. Run_o : out std_logic;
  21. Data_i : in std_logic
  22. );
  23. end entity FiRoCtrlE;
  24. architecture rtl of FiRoCtrlE is
  25. signal s_firo_run : std_logic;
  26. signal s_firo_valid : std_logic;
  27. type t_neumann_state is (BIT1, BIT2, BIT3, BIT4);
  28. signal s_neumann_state : t_neumann_state;
  29. signal s_neumann_buffer : std_logic_vector(2 downto 0);
  30. type t_register_state is (SLEEP, COLLECT);
  31. signal s_register_state : t_register_state;
  32. signal s_register_enable : std_logic;
  33. signal s_register_din : std_logic_vector(1 downto 0);
  34. signal s_register_data : std_logic_vector(8 downto 0);
  35. signal s_register_counter : unsigned(2 downto 0);
  36. signal s_register_length : natural range 1 to 2;
  37. signal s_data : std_logic_vector(3 downto 0);
  38. begin
  39. Run_o <= s_run when s_register_state = COLLECT else '0';
  40. s_data <= s_neumann_buffer & Data_i;
  41. ControllerP : process (Clk_i) is
  42. variable v_wait_cnt : unsigned(7 downto 0);
  43. variable v_run_cnt : unsigned(7 downto 0);
  44. begin
  45. if (rising_edge(Clk_i)) then
  46. if (s_register_state = SLEEP) then
  47. v_wait_cnt := unsigned(Wait_i);
  48. v_run_cnt := unsigned(Run_i);
  49. s_firo_run <= '0';
  50. s_firo_valid <= '0';
  51. else
  52. s_firo_valid <= '0';
  53. if (v_wait_cnt = 0) then
  54. s_firo_run <= '1';
  55. else
  56. v_wait_cnt := v_wait_cnt - 1;
  57. end if;
  58. if (v_run_cnt = 0) then
  59. s_firo_run <= '0';
  60. elsif (v_run_cnt = 1) then
  61. s_firo_valid <= '1';
  62. else
  63. if (v_wait_cnt = 0) then
  64. v_run_cnt := v_run_cnt - 1;
  65. end if;
  66. end if;
  67. end if;
  68. end if;
  69. end process ControllerP;
  70. extractor : if EXTRACT generate
  71. VonNeumannP : process (Clk_i) is
  72. begin
  73. if (rising_edge(Clk_i)) then
  74. if (Reset_i = '0') then
  75. s_neumann_state <= BIT1;
  76. else
  77. case s_neumann_state is
  78. when BIT1 =>
  79. s_register_enable <= '0';
  80. if (s_firo_valid = '1') then
  81. s_neumann_buffer(2) <= Data_i;
  82. s_neumann_state <= BIT2;
  83. end if;
  84. when BIT2 =>
  85. if (s_firo_valid = '1') then
  86. s_neumann_buffer(1) <= Data_i;
  87. s_neumann_state <= BIT3;
  88. end if;
  89. when BIT3 =>
  90. if (s_firo_valid = '1') then
  91. s_neumann_buffer(0) <= Data_i;
  92. s_neumann_state <= BIT4;
  93. end if;
  94. when BIT4 =>
  95. if (s_firo_valid = '1') then
  96. s_register_enable <= '1';
  97. s_register_length <= 1;
  98. s_register_din <= "00";
  99. s_neumann_state <= BIT1;
  100. case (s_data) is
  101. when x"5" =>
  102. s_register_din <= "01";
  103. when x"1" | x"6" | x"7" =>
  104. s_register_length <= 2;
  105. when x"2" | x"9" | x"b" =>
  106. s_register_din <= "01";
  107. s_register_length <= 2;
  108. when x"4" | x"a" | x"d" =>
  109. s_register_din <= "10";
  110. s_register_length <= 2;
  111. when x"8" | x"c" | x"e" =>
  112. s_register_din <= "11";
  113. s_register_length <= 2;
  114. when x"0" | x"f" =>
  115. s_register_enable <= '0';
  116. when others => -- incl. x"3"
  117. null;
  118. end case;
  119. end if;
  120. when others =>
  121. null;
  122. end case;
  123. end if;
  124. end if;
  125. end process VonNeumannP;
  126. end generate;
  127. no_extractor : if not(EXTRACT) generate
  128. s_register_enable <= s_firo_valid;
  129. s_register_din(0) <= Data_i;
  130. s_register_length <= 1;
  131. end generate;
  132. Data_o <= s_register_data(7 downto 0);
  133. ShiftRegisterP : process (Clk_i) is
  134. begin
  135. if (rising_edge(Clk_i)) then
  136. if (Reset_i = '0') then
  137. s_register_counter <= (others => '1');
  138. s_register_state <= SLEEP;
  139. DataValid_o <= '0';
  140. else
  141. case s_register_state is
  142. when SLEEP =>
  143. DataValid_o <= '0';
  144. if (Start_i = '1' and Run_i /= x"00") then
  145. s_register_state <= COLLECT;
  146. s_register_data(0) <= s_register_data(8);
  147. end if;
  148. when COLLECT =>
  149. if (s_register_enable = '1') then
  150. if (s_register_counter = 0) then
  151. s_register_data <= s_register_din(1) & s_register_data(6 downto 0) & s_register_din(0);
  152. DataValid_o <= '1';
  153. s_register_state <= SLEEP;
  154. elsif (s_register_counter = 1) then
  155. if (s_register_length = 1) then
  156. s_register_data(7 downto 0) <= s_register_data(6 downto 0) & s_register_din(0);
  157. end if;
  158. if (s_register_length = 2) then
  159. s_register_data(7 downto 0) <= s_register_data(5 downto 0) & s_register_din;
  160. DataValid_o <= '1';
  161. s_register_state <= SLEEP;
  162. end if;
  163. else
  164. if (s_register_length = 1) then
  165. s_register_data(7 downto 0) <= s_register_data(6 downto 0) & s_register_din(0);
  166. else
  167. s_register_data(7 downto 0) <= s_register_data(5 downto 0) & s_register_din;
  168. end if;
  169. end if;
  170. s_register_counter <= s_register_counter - s_register_length;
  171. end if;
  172. when others =>
  173. null;
  174. end case;
  175. end if;
  176. end if;
  177. end process ShiftRegisterP;
  178. end architecture rtl;