|
@ -0,0 +1,212 @@ |
|
|
|
|
|
library ieee; |
|
|
|
|
|
use ieee.std_logic_1164.all; |
|
|
|
|
|
use ieee.numeric_std.all; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
entity FiRoCtrlE is |
|
|
|
|
|
generic ( |
|
|
|
|
|
EXTRACT : boolean := true |
|
|
|
|
|
); |
|
|
|
|
|
port ( |
|
|
|
|
|
--+ system if |
|
|
|
|
|
Clk_i : in std_logic; |
|
|
|
|
|
Reset_i : in std_logic; |
|
|
|
|
|
--+ ctrl/status |
|
|
|
|
|
Start_i : in std_logic; |
|
|
|
|
|
--+ rnd data |
|
|
|
|
|
DataValid_o : out std_logic; |
|
|
|
|
|
Data_o : out std_logic_vector(7 downto 0); |
|
|
|
|
|
-- firo |
|
|
|
|
|
Run_o : out std_logic; |
|
|
|
|
|
Data_i : in std_logic |
|
|
|
|
|
); |
|
|
|
|
|
end entity FiRoCtrlE; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
architecture rtl of FiRoCtrlE is |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
signal s_clk_counter : unsigned(4 downto 0); |
|
|
|
|
|
signal s_run : std_logic; |
|
|
|
|
|
signal s_firo_valid : std_logic; |
|
|
|
|
|
|
|
|
|
|
|
type t_neumann_state is (BIT1, BIT2, BIT3, BIT4); |
|
|
|
|
|
signal s_neumann_state : t_neumann_state; |
|
|
|
|
|
signal s_neumann_buffer : std_logic_vector(2 downto 0); |
|
|
|
|
|
|
|
|
|
|
|
type t_register_state is (SLEEP, COLLECT); |
|
|
|
|
|
signal s_register_state : t_register_state; |
|
|
|
|
|
signal s_register_enable : std_logic; |
|
|
|
|
|
signal s_register_din : std_logic_vector(1 downto 0); |
|
|
|
|
|
signal s_register_data : std_logic_vector(8 downto 0); |
|
|
|
|
|
signal s_register_counter : unsigned(2 downto 0); |
|
|
|
|
|
signal s_register_length : natural range 1 to 2; |
|
|
|
|
|
|
|
|
|
|
|
signal s_data : std_logic_vector(3 downto 0); |
|
|
|
|
|
|
|
|
|
|
|
begin |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Run_o <= s_run when s_register_state = COLLECT else '0'; |
|
|
|
|
|
s_data <= s_neumann_buffer & Data_i; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ControllerP : process (Clk_i) is |
|
|
|
|
|
variable v_clk_cnt : unsigned(4 downto 0); |
|
|
|
|
|
begin |
|
|
|
|
|
if (rising_edge(Clk_i)) then |
|
|
|
|
|
if (s_register_state = SLEEP) then |
|
|
|
|
|
v_clk_cnt := (others => '1'); |
|
|
|
|
|
s_run <= '0'; |
|
|
|
|
|
s_firo_valid <= '0'; |
|
|
|
|
|
else |
|
|
|
|
|
s_firo_valid <= '0'; |
|
|
|
|
|
if (v_clk_cnt = 23 and s_run = '0') then |
|
|
|
|
|
s_run <= '1'; |
|
|
|
|
|
v_clk_cnt := (others => '1'); |
|
|
|
|
|
end if; |
|
|
|
|
|
if (v_clk_cnt = 12 and s_run = '1') then |
|
|
|
|
|
s_run <= '0'; |
|
|
|
|
|
v_clk_cnt := (others => '1'); |
|
|
|
|
|
end if; |
|
|
|
|
|
if (v_clk_cnt = 13 and s_run = '1') then |
|
|
|
|
|
s_firo_valid := '1'; |
|
|
|
|
|
end if; |
|
|
|
|
|
v_clk_cnt := v_clk_cnt - 1; |
|
|
|
|
|
end if; |
|
|
|
|
|
end if; |
|
|
|
|
|
end process ControllerP; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
extractor : if EXTRACT generate |
|
|
|
|
|
VonNeumannP : process (Clk_i) is |
|
|
|
|
|
begin |
|
|
|
|
|
if (rising_edge(Clk_i)) then |
|
|
|
|
|
if (Reset_i = '0') then |
|
|
|
|
|
s_neumann_state <= BIT1; |
|
|
|
|
|
--s_neumann_buffer <= "000"; |
|
|
|
|
|
--s_register_enable <= '0'; |
|
|
|
|
|
--s_register_din <= "00"; |
|
|
|
|
|
else |
|
|
|
|
|
case s_neumann_state is |
|
|
|
|
|
|
|
|
|
|
|
when BIT1 => |
|
|
|
|
|
s_register_enable <= '0'; |
|
|
|
|
|
if (s_firo_valid = '1') then |
|
|
|
|
|
s_neumann_buffer(2) <= Data_i; |
|
|
|
|
|
s_neumann_state <= BIT2; |
|
|
|
|
|
end if; |
|
|
|
|
|
|
|
|
|
|
|
when BIT2 => |
|
|
|
|
|
if (s_firo_valid = '1') then |
|
|
|
|
|
s_neumann_buffer(1) <= Data_i; |
|
|
|
|
|
s_neumann_state <= BIT3; |
|
|
|
|
|
end if; |
|
|
|
|
|
|
|
|
|
|
|
when BIT3 => |
|
|
|
|
|
if (s_firo_valid = '1') then |
|
|
|
|
|
s_neumann_buffer(0) <= Data_i; |
|
|
|
|
|
s_neumann_state <= BIT4; |
|
|
|
|
|
end if; |
|
|
|
|
|
|
|
|
|
|
|
when BIT4 => |
|
|
|
|
|
if (s_firo_valid = '1') then |
|
|
|
|
|
s_register_enable <= '1'; |
|
|
|
|
|
s_register_length <= 1; |
|
|
|
|
|
s_register_din <= "00"; |
|
|
|
|
|
s_neumann_state <= BIT1; |
|
|
|
|
|
case (s_data) is |
|
|
|
|
|
when x"5" => |
|
|
|
|
|
s_register_din <= "01"; |
|
|
|
|
|
when x"1" | x"6" | x"7" => |
|
|
|
|
|
s_register_length <= 2; |
|
|
|
|
|
when x"2" | x"9" | x"b" => |
|
|
|
|
|
s_register_din <= "01"; |
|
|
|
|
|
s_register_length <= 2; |
|
|
|
|
|
when x"4" | x"a" | x"d" => |
|
|
|
|
|
s_register_din <= "10"; |
|
|
|
|
|
s_register_length <= 2; |
|
|
|
|
|
when x"8" | x"c" | x"e" => |
|
|
|
|
|
s_register_din <= "11"; |
|
|
|
|
|
s_register_length <= 2; |
|
|
|
|
|
when x"0" | x"f" => |
|
|
|
|
|
s_register_enable <= '0'; |
|
|
|
|
|
when others => -- incl. x"3" |
|
|
|
|
|
null; |
|
|
|
|
|
end case; |
|
|
|
|
|
end if; |
|
|
|
|
|
|
|
|
|
|
|
when others => |
|
|
|
|
|
null; |
|
|
|
|
|
|
|
|
|
|
|
end case; |
|
|
|
|
|
end if; |
|
|
|
|
|
end if; |
|
|
|
|
|
end process VonNeumannP; |
|
|
|
|
|
end generate; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
no_extractor : if not(EXTRACT) generate |
|
|
|
|
|
s_register_enable <= s_firo_valid; |
|
|
|
|
|
s_register_din(0) <= Data_i; |
|
|
|
|
|
s_register_length <= 1; |
|
|
|
|
|
end generate; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Data_o <= s_register_data(7 downto 0); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ShiftRegisterP : process (Clk_i) is |
|
|
|
|
|
begin |
|
|
|
|
|
if (rising_edge(Clk_i)) then |
|
|
|
|
|
if (Reset_i = '0') then |
|
|
|
|
|
s_register_counter <= (others => '1'); |
|
|
|
|
|
s_register_state <= SLEEP; |
|
|
|
|
|
DataValid_o <= '0'; |
|
|
|
|
|
else |
|
|
|
|
|
case s_register_state is |
|
|
|
|
|
|
|
|
|
|
|
when SLEEP => |
|
|
|
|
|
if (Start_i = '1') then |
|
|
|
|
|
DataValid_o <= '0'; |
|
|
|
|
|
s_register_state <= COLLECT; |
|
|
|
|
|
s_register_data(0) <= s_register_data(8); |
|
|
|
|
|
end if; |
|
|
|
|
|
|
|
|
|
|
|
when COLLECT => |
|
|
|
|
|
if (s_register_enable = '1') then |
|
|
|
|
|
if (s_register_counter = 0) then |
|
|
|
|
|
s_register_data <= s_register_din(1) & s_register_data(6 downto 0) & s_register_din(0); |
|
|
|
|
|
DataValid_o <= '1'; |
|
|
|
|
|
s_register_state <= SLEEP; |
|
|
|
|
|
elsif (s_register_counter = 1) then |
|
|
|
|
|
if (s_register_length = 1) then |
|
|
|
|
|
s_register_data(7 downto 0) <= s_register_data(6 downto 0) & s_register_din(0); |
|
|
|
|
|
end if; |
|
|
|
|
|
if (s_register_length = 2) then |
|
|
|
|
|
s_register_data(7 downto 0) <= s_register_data(5 downto 0) & s_register_din; |
|
|
|
|
|
DataValid_o <= '1'; |
|
|
|
|
|
s_register_state <= SLEEP; |
|
|
|
|
|
end if; |
|
|
|
|
|
else |
|
|
|
|
|
if (s_register_length = 1) then |
|
|
|
|
|
s_register_data(7 downto 0) <= s_register_data(6 downto 0) & s_register_din(0); |
|
|
|
|
|
else |
|
|
|
|
|
s_register_data(7 downto 0) <= s_register_data(5 downto 0) & s_register_din; |
|
|
|
|
|
end if; |
|
|
|
|
|
end if; |
|
|
|
|
|
s_register_counter <= s_register_counter - s_register_length; |
|
|
|
|
|
end if; |
|
|
|
|
|
|
|
|
|
|
|
when others => |
|
|
|
|
|
null; |
|
|
|
|
|
|
|
|
|
|
|
end case; |
|
|
|
|
|
end if; |
|
|
|
|
|
end if; |
|
|
|
|
|
end process ShiftRegisterP; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
end architecture rtl; |