library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; library work; use work.reg32.all; use work.task.all; entity rand is port ( clk : in std_logic; reset : in std_logic; task_start : in std_logic; task_state : out work.task.State; seed : in work.reg32.word; signal_write : out std_logic; signal_writedata : out std_logic_vector( 31 downto 0 ) ); end entity rand; architecture rtl of rand is signal current_task_state : work.task.State; signal next_task_state : work.task.State; signal index : integer range 0 to work.task.STREAM_LEN; --Signale anlegen: signal data_valid_intern : std_logic; --um skalieren zu gehen --signal angle_intern : signed(31 downto 0); --signal busy_intern : std_logic; --signal result_valid_intern : std_logic; --signal sine_intern : signed(31 downto 0); --State Machine anlegen: type CalcState is( CALC_IDLE, CALC_RANDOMISIEREN,--2) neuen Randomwert berechnen --(dauert einige Takte) CALC_SKALIEREN,--3) den berechneten Wert skalieren CALC_IN_FIFO_ABSPEICHERN); --4) im FIFO abspeichern signal current_calc_state : CalcState; signal next_calc_state : CalcState; begin --IP-Core instanzieren und entsprechende Signale verbinden: task_state_transitions : process ( current_task_state, task_start, index ) is begin next_task_state <= current_task_state; case current_task_state is when work.task.TASK_IDLE => if ( task_start = '1' ) then next_task_state <= work.task.TASK_RUNNING; end if; when work.task.TASK_RUNNING => if ( index = work.task.STREAM_LEN - 1 ) then next_task_state <= work.task.TASK_DONE; end if; when work.task.TASK_DONE => if ( task_start = '1' ) then next_task_state <= work.task.TASK_RUNNING; end if; end case; end process task_state_transitions; --ZUSTANDSMASCHINE: calc_state_transitions : process (all) is begin next_calc_state <= current_calc_state; case current_calc_state is when CALC_IDLE => if(current_task_state = work.task.TASK_RUNNING) then next_calc_state <= CALC_RANDOMISIEREN; end if; when CALC_RANDOMISIEREN => --if(result_valid_intern = '1' and busy_intern = '0') then--busy_intern = '0' if(data_valid_intern = '1') then next_calc_state <= CALC_SKALIEREN; end if; when CALC_SKALIEREN => next_calc_state <= CALC_IN_FIFO_ABSPEICHERN; when CALC_IN_FIFO_ABSPEICHERN => next_calc_state <= CALC_RANDOMISIEREN; if(index = 1024) then next_calc_state <= CALC_IDLE; end if; end case; end process calc_state_transitions; sync : process ( clk, reset ) is --VARIABLEN: VARIABLE randomisiert : signed ( 31 downto 0 ); VARIABLE scaled : signed ( 31 downto 0 ); random_number_word : std_logic_vector(31 downto 0); variable mask_bit_0 : std_logic_vector(31 downto 0); variable mask_bit_1 : std_logic_vector(31 downto 0); variable mask_bit_21 : std_logic_vector(31 downto 0); variable mask_bit_31 : std_logic_vector(31 downto 0); variable xor_result : std_logic_vector(0 downto 0); variable shifted : std_logic_vector(31 downto 0); variable exponent : std_logic_vector(7 downto 0); variable shifted_modified : std_logic_vector(31 downto 0); variable shifted_exponent : std_logic_vector(31 downto 0); variable shifted_modifiziert : std_logic_vector(31 downto 0); begin if ( reset = '1' ) then current_task_state <= work.task.TASK_IDLE; index <= 0; --START VALUES: randomisiert := (others => '0'); data_valid_intern <= '0'; signal_write <= '0'; signal_writedata <= ( others => '0' ); elsif ( rising_edge( clk ) ) then current_task_state <= next_task_state; case next_task_state is when work.task.TASK_IDLE => index <= 0; signal_write <= '0'; when work.task.TASK_RUNNING => index <= index + 1; signal_write <= '1'; signal_writedata <= ( others => '0' ); when work.task.TASK_DONE => index <= 0; signal_write <= '0'; end case; --ZUSTANDSMACHINE LOGIK: --A: current_calc_state <= next_calc_state; data_valid_intern <= '0'; signal_write <= '0'; case next_calc_state is when CALC_IDLE => --angle_intern <= (others => '0'); index <= 0; when CALC_RANDOMISIEREN => randomisiert := 5; if (index == 0) then random_number_word := seed; end if; -- Bits extrahieren und XOR durchführen bit_0 := random_number_word(0) and mask_bit_0(0); bit_1 := random_number_word(1) and mask_bit_1(1); bit_21 := random_number_word(21) and mask_bit_21(21); bit_31 := random_number_word(31) and mask_bit_31(31); xor_result := bit_0 xor bit_1 xor bit_21 xor bit_31; -- Shift um 1 nach rechts shifted := random_number_word(30 downto 0) & '0'; shifted(31) := xor_result(0); -- XOR-Ergebnis an das MSB (Bit 31) setzen -- Ergebnis ausgeben shifted_result <= shifted; data_valid_intern <= '1'; when CALC_SKALIEREN => --if(result_valid_intern = '1') then scaled := randomisiert; --scaled := 6; --randomisiert(30 downto 23) := randomisiert(30 downto 23) + ( signed(amplitude(30 downto 23)) - 127); --end if; -- Exponent extrahieren exponent := shifted_result(30 downto 23); -- Überprüfen, ob das 7. Bit des Exponenten gesetzt ist if (exponent(7) = '1') then exponent := exponent and "10000001"; else exponent := exponent or "01111100"; end if; -- Verschiebung vorbereiten shifted_modified := shifted_result; shifted_exponent := ('0' & exponent) & (others => '0'); -- Verschiedene Teile kombinieren shifted_modifiziert := shifted_modified and x"807FFFFF"; shifted_modifiziert := shifted_modifiziert or shifted_exponent; -- Ergebnis ausgeben scaled_modified_result <= shifted_modifiziert; when CALC_IN_FIFO_ABSPEICHERN => if(index > 1) then signal_writedata <= std_logic_vector(scaled); end if; signal_write <= '1'; index <= index + 1; end case; --E end if; end process sync; task_state <= current_task_state; end architecture rtl;