255 lines
6.7 KiB
VHDL
Raw Normal View History

2023-10-31 07:47:27 +01:00
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;
2024-01-09 08:41:42 +01:00
--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;
2023-10-31 07:47:27 +01:00
begin
2024-01-09 08:41:42 +01:00
--IP-Core instanzieren und entsprechende Signale verbinden:
2023-10-31 07:47:27 +01:00
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;
2024-01-09 08:41:42 +01:00
--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;
2023-10-31 07:47:27 +01:00
sync : process ( clk, reset ) is
2024-01-09 08:41:42 +01:00
--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);
2023-10-31 07:47:27 +01:00
begin
if ( reset = '1' ) then
current_task_state <= work.task.TASK_IDLE;
index <= 0;
2024-01-09 08:41:42 +01:00
--START VALUES:
randomisiert := (others => '0');
data_valid_intern <= '0';
signal_write <= '0';
signal_writedata <= ( others => '0' );
2023-10-31 07:47:27 +01:00
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;
2024-01-09 08:41:42 +01:00
--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
2023-10-31 07:47:27 +01:00
end if;
end process sync;
task_state <= current_task_state;
end architecture rtl;
2024-01-09 08:41:42 +01:00