From 0e2170a504916d70df236ba9e1e4fe5454452ce1 Mon Sep 17 00:00:00 2001 From: tmeissner Date: Mon, 8 Dec 2014 22:01:23 +0100 Subject: [PATCH] add Fibonacci RNG and control unit; using register #0 as control/status and register #1 as data register for the RNG instance --- raspiFpga/src/FiRoCtrlE.vhd | 212 +++++++++++++++++++++++++++++++ raspiFpga/src/FiRoE.vhd | 69 ++++++++++ raspiFpga/src/RaspiFpgaCtrlE.vhd | 18 ++- raspiFpga/src/RaspiFpgaE.vhd | 79 +++++++++++- 4 files changed, 368 insertions(+), 10 deletions(-) create mode 100644 raspiFpga/src/FiRoCtrlE.vhd create mode 100644 raspiFpga/src/FiRoE.vhd diff --git a/raspiFpga/src/FiRoCtrlE.vhd b/raspiFpga/src/FiRoCtrlE.vhd new file mode 100644 index 0000000..cebd7bc --- /dev/null +++ b/raspiFpga/src/FiRoCtrlE.vhd @@ -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; diff --git a/raspiFpga/src/FiRoE.vhd b/raspiFpga/src/FiRoE.vhd new file mode 100644 index 0000000..63d05ad --- /dev/null +++ b/raspiFpga/src/FiRoE.vhd @@ -0,0 +1,69 @@ +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + + + +entity FiRoE is + generic ( + TOGGLE : boolean := true + ); + port ( + FiRo_o : out std_logic; + Run_i : in std_logic + ); +end entity FiRoE; + + + +architecture rtl of FiRoE is + + + --+ signal for inverter loop + signal s_ring : std_logic_vector(15 downto 0); + signal s_tff : std_logic; + + --+ attributes for synplify synthesis tool to preserve inverter loop + attribute syn_keep : boolean; + attribute syn_hier : string; + attribute syn_hier of rtl : architecture is "hard"; + attribute syn_keep of s_ring : signal is true; + attribute syn_keep of s_tff : signal is true; + + +begin + + + FiroRingG : for index in 1 to 15 generate + + s_ring(index) <= not(s_ring(index - 1)); + + end generate FiroRingG; + + s_ring(0) <= (s_ring(15) xor s_ring(14) xor s_ring(7) xor s_ring(6) xor s_ring(5) xor s_ring(4) xor s_ring(2)) and Run_i; + + + WithToggleG : if TOGGLE generate + + tffP : process(Run_i, s_ring(15)) is + begin + if(Run_i = '0') then + s_tff <= '0'; + elsif(rising_edge(s_ring(15))) then + s_tff <= not s_tff; + end if; + end process tffP; + + FiRo_o <= s_ring(15) xor s_tff; + + end generate WithToggleG; + + + WithoutToggleG : if not(TOGGLE) generate + + FiRo_o <= s_ring(15); + + end generate WithoutToggleG; + + +end architecture rtl; diff --git a/raspiFpga/src/RaspiFpgaCtrlE.vhd b/raspiFpga/src/RaspiFpgaCtrlE.vhd index a43ebbd..4eda220 100644 --- a/raspiFpga/src/RaspiFpgaCtrlE.vhd +++ b/raspiFpga/src/RaspiFpgaCtrlE.vhd @@ -18,7 +18,11 @@ entity RaspiFpgaCtrlE is LocalAck_i : in std_logic; LocalError_i : in std_logic; --+ EFB if - EfbSpiIrq_i : in std_logic + EfbSpiIrq_i : in std_logic; + --+ RNG if + RngStart_o : out std_logic; + RngDataValid_i : in std_logic; + RngData_i : in std_logic_vector(7 downto 0) ); end entity RaspiFpgaCtrlE; @@ -129,13 +133,13 @@ begin s_cmdctrl_fsm <= INT_CLEAR_SET; end if; - when INT_CLEAR_SET => + when INT_CLEAR_SET => s_cmdctrl_fsm <= INT_CLEAR_ACK; - + when INT_CLEAR_ACK => if (LocalAck_i = '1') then s_cmdctrl_fsm <= TXDR_SET; - end if; + end if; when others => null; @@ -201,9 +205,15 @@ begin if (Rst_n_i = '0') then s_register <= (others => (others => '0')); else + s_register(0)(0) <= '0'; --* reset RNG start after each clock cycle if (s_register_we = '1') then s_register(s_register_address) <= LocalData_i; end if; + --+ register RNG data + if (RngDataValid_i = '1') then + s_register(0)(1) <= '1'; + s_register(1) <= RngData_i; + end if; end if; end if; end process RegisterFileP; diff --git a/raspiFpga/src/RaspiFpgaE.vhd b/raspiFpga/src/RaspiFpgaE.vhd index 9ff3361..0ef80ae 100644 --- a/raspiFpga/src/RaspiFpgaE.vhd +++ b/raspiFpga/src/RaspiFpgaE.vhd @@ -70,11 +70,46 @@ architecture rtl of RaspiFpgaE is LocalAck_i : in std_logic; LocalError_i : in std_logic; --+ EFB if - EfbSpiIrq_i : in std_logic + EfbSpiIrq_i : in std_logic; + --+ RNG if + RngStart_o : out std_logic; + RngDataValid_i : in std_logic; + RngData_i : in std_logic_vector(7 downto 0) ); end component RaspiFpgaCtrlE; + component 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 component FiRoCtrlE; + + + component FiRoE is + generic ( + TOGGLE : boolean := true + ); + port ( + FiRo_o : out std_logic; + Run_i : in std_logic + ); + end component FiRoE; + + --+ EFB SPI slave component component EfbSpiSlave is port ( @@ -98,11 +133,9 @@ architecture rtl of RaspiFpgaE is --+ oscillator component component OSCH is - -- synthesis translate_off generic ( NOM_FREQ : string := "26.60" ); - -- synthesis translate_on port ( STDBY : in std_logic; OSC : out std_logic; @@ -145,18 +178,23 @@ architecture rtl of RaspiFpgaE is signal s_local_write_data : std_logic_vector(7 downto 0); signal s_local_ack : std_logic; + --+ RNG signals + signal s_rng_start : std_logic; + signal s_rng_data_valid : std_logic; + signal s_rng_data : std_logic_vector(7 downto 0); + signal s_firo_run : std_logic; + signal s_firo_data : std_logic; + begin --+ Oscillator instance - --+ It's generating our 26.6 MHz csystem lock + --+ It's generating our 26.6 MHz system lock i_OSC : OSCH - -- synthesis off generic map ( NOM_FREQ => "26.60" ) - -- synthesis on port map ( STDBY => '0', OSC => s_sys_clk, @@ -250,6 +288,35 @@ begin ); + i_FiRoCtrlE : FiRoCtrlE + generic map ( + EXTRACT => true + ) + port map ( + --+ system if + Clk_i => s_sys_clk, + Reset_i => s_sys_rst, + --+ ctrl/status + Start_i => s_rng_start, + --+ rnd data + DataValid_o => s_rng_data_valid, + Data_o => s_rng_data, + -- firo + Run_o => s_firo_run, + Data_i => s_firo_data + ); + + + i_FiRoE : FiRoE + generic map ( + TOGGLE => true + ) + port map ( + FiRo_o => s_firo_data, + Run_i => s_firo_run + ); + + RaspiIrq_o <= '0';