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.

189 lines
5.8 KiB

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