Studentenversion des ESY6/A Praktikums "signal_processing".
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

rand.vhd 6.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. use ieee.numeric_std.all;
  4. library work;
  5. use work.reg32.all;
  6. use work.task.all;
  7. entity rand is
  8. port (
  9. clk : in std_logic;
  10. reset : in std_logic;
  11. task_start : in std_logic;
  12. task_state : out work.task.State;
  13. seed : in work.reg32.word;
  14. signal_write : out std_logic;
  15. signal_writedata : out std_logic_vector( 31 downto 0 )
  16. );
  17. end entity rand;
  18. architecture rtl of rand is
  19. signal current_task_state : work.task.State;
  20. signal next_task_state : work.task.State;
  21. signal index : integer range 0 to work.task.STREAM_LEN;
  22. --Signale anlegen:
  23. signal data_valid_intern : std_logic; --um skalieren zu gehen
  24. --signal angle_intern : signed(31 downto 0);
  25. --signal busy_intern : std_logic;
  26. --signal result_valid_intern : std_logic;
  27. --signal sine_intern : signed(31 downto 0);
  28. --State Machine anlegen:
  29. type CalcState is(
  30. CALC_IDLE,
  31. CALC_RANDOMISIEREN,--2) neuen Randomwert berechnen
  32. --(dauert einige Takte)
  33. CALC_SKALIEREN,--3) den berechneten Wert skalieren
  34. CALC_IN_FIFO_ABSPEICHERN); --4) im FIFO abspeichern
  35. signal current_calc_state : CalcState;
  36. signal next_calc_state : CalcState;
  37. begin
  38. --IP-Core instanzieren und entsprechende Signale verbinden:
  39. task_state_transitions : process ( current_task_state, task_start, index ) is
  40. begin
  41. next_task_state <= current_task_state;
  42. case current_task_state is
  43. when work.task.TASK_IDLE =>
  44. if ( task_start = '1' ) then
  45. next_task_state <= work.task.TASK_RUNNING;
  46. end if;
  47. when work.task.TASK_RUNNING =>
  48. if ( index = work.task.STREAM_LEN - 1 ) then
  49. next_task_state <= work.task.TASK_DONE;
  50. end if;
  51. when work.task.TASK_DONE =>
  52. if ( task_start = '1' ) then
  53. next_task_state <= work.task.TASK_RUNNING;
  54. end if;
  55. end case;
  56. end process task_state_transitions;
  57. --ZUSTANDSMASCHINE:
  58. calc_state_transitions : process (all) is
  59. begin
  60. next_calc_state <= current_calc_state;
  61. case current_calc_state is
  62. when CALC_IDLE =>
  63. if(current_task_state = work.task.TASK_RUNNING) then
  64. next_calc_state <= CALC_RANDOMISIEREN;
  65. end if;
  66. when CALC_RANDOMISIEREN =>
  67. --if(result_valid_intern = '1' and busy_intern = '0') then--busy_intern = '0'
  68. if(data_valid_intern = '1') then
  69. next_calc_state <= CALC_SKALIEREN;
  70. end if;
  71. when CALC_SKALIEREN =>
  72. next_calc_state <= CALC_IN_FIFO_ABSPEICHERN;
  73. when CALC_IN_FIFO_ABSPEICHERN =>
  74. next_calc_state <= CALC_RANDOMISIEREN;
  75. if(index = 1024) then
  76. next_calc_state <= CALC_IDLE;
  77. end if;
  78. end case;
  79. end process calc_state_transitions;
  80. sync : process ( clk, reset ) is
  81. --VARIABLEN:
  82. VARIABLE randomisiert : signed ( 31 downto 0 );
  83. VARIABLE scaled : signed ( 31 downto 0 );
  84. random_number_word : std_logic_vector(31 downto 0);
  85. variable mask_bit_0 : std_logic_vector(31 downto 0);
  86. variable mask_bit_1 : std_logic_vector(31 downto 0);
  87. variable mask_bit_21 : std_logic_vector(31 downto 0);
  88. variable mask_bit_31 : std_logic_vector(31 downto 0);
  89. variable xor_result : std_logic_vector(0 downto 0);
  90. variable shifted : std_logic_vector(31 downto 0);
  91. variable exponent : std_logic_vector(7 downto 0);
  92. variable shifted_modified : std_logic_vector(31 downto 0);
  93. variable shifted_exponent : std_logic_vector(31 downto 0);
  94. variable shifted_modifiziert : std_logic_vector(31 downto 0);
  95. begin
  96. if ( reset = '1' ) then
  97. current_task_state <= work.task.TASK_IDLE;
  98. index <= 0;
  99. --START VALUES:
  100. randomisiert := (others => '0');
  101. data_valid_intern <= '0';
  102. signal_write <= '0';
  103. signal_writedata <= ( others => '0' );
  104. elsif ( rising_edge( clk ) ) then
  105. current_task_state <= next_task_state;
  106. case next_task_state is
  107. when work.task.TASK_IDLE =>
  108. index <= 0;
  109. signal_write <= '0';
  110. when work.task.TASK_RUNNING =>
  111. index <= index + 1;
  112. signal_write <= '1';
  113. signal_writedata <= ( others => '0' );
  114. when work.task.TASK_DONE =>
  115. index <= 0;
  116. signal_write <= '0';
  117. end case;
  118. --ZUSTANDSMACHINE LOGIK:
  119. --A:
  120. current_calc_state <= next_calc_state;
  121. data_valid_intern <= '0';
  122. signal_write <= '0';
  123. case next_calc_state is
  124. when CALC_IDLE =>
  125. --angle_intern <= (others => '0');
  126. index <= 0;
  127. when CALC_RANDOMISIEREN =>
  128. randomisiert := 5;
  129. if (index == 0) then
  130. random_number_word := seed;
  131. end if;
  132. -- Bits extrahieren und XOR durchführen
  133. bit_0 := random_number_word(0) and mask_bit_0(0);
  134. bit_1 := random_number_word(1) and mask_bit_1(1);
  135. bit_21 := random_number_word(21) and mask_bit_21(21);
  136. bit_31 := random_number_word(31) and mask_bit_31(31);
  137. xor_result := bit_0 xor bit_1 xor bit_21 xor bit_31;
  138. -- Shift um 1 nach rechts
  139. shifted := random_number_word(30 downto 0) & '0';
  140. shifted(31) := xor_result(0); -- XOR-Ergebnis an das MSB (Bit 31) setzen
  141. -- Ergebnis ausgeben
  142. shifted_result <= shifted;
  143. data_valid_intern <= '1';
  144. when CALC_SKALIEREN =>
  145. --if(result_valid_intern = '1') then
  146. scaled := randomisiert;
  147. --scaled := 6;
  148. --randomisiert(30 downto 23) := randomisiert(30 downto 23) + ( signed(amplitude(30 downto 23)) - 127);
  149. --end if;
  150. -- Exponent extrahieren
  151. exponent := shifted_result(30 downto 23);
  152. -- Überprüfen, ob das 7. Bit des Exponenten gesetzt ist
  153. if (exponent(7) = '1') then
  154. exponent := exponent and "10000001";
  155. else
  156. exponent := exponent or "01111100";
  157. end if;
  158. -- Verschiebung vorbereiten
  159. shifted_modified := shifted_result;
  160. shifted_exponent := ('0' & exponent) & (others => '0');
  161. -- Verschiedene Teile kombinieren
  162. shifted_modifiziert := shifted_modified and x"807FFFFF";
  163. shifted_modifiziert := shifted_modifiziert or shifted_exponent;
  164. -- Ergebnis ausgeben
  165. scaled_modified_result <= shifted_modifiziert;
  166. when CALC_IN_FIFO_ABSPEICHERN =>
  167. if(index > 1) then
  168. signal_writedata <= std_logic_vector(scaled);
  169. end if;
  170. signal_write <= '1';
  171. index <= index + 1;
  172. end case;
  173. --E
  174. end if;
  175. end process sync;
  176. task_state <= current_task_state;
  177. end architecture rtl;