Browse Source

add Fibonacci RNG and control unit; using register #0 as control/status and register #1 as data register for the RNG instance

master
T. Meissner 10 years ago
parent
commit
0e2170a504
4 changed files with 368 additions and 10 deletions
  1. +212
    -0
      raspiFpga/src/FiRoCtrlE.vhd
  2. +69
    -0
      raspiFpga/src/FiRoE.vhd
  3. +14
    -4
      raspiFpga/src/RaspiFpgaCtrlE.vhd
  4. +73
    -6
      raspiFpga/src/RaspiFpgaE.vhd

+ 212
- 0
raspiFpga/src/FiRoCtrlE.vhd View File

@ -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;

+ 69
- 0
raspiFpga/src/FiRoE.vhd View File

@ -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;

+ 14
- 4
raspiFpga/src/RaspiFpgaCtrlE.vhd View File

@ -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;


+ 73
- 6
raspiFpga/src/RaspiFpgaE.vhd View File

@ -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';


Loading…
Cancel
Save