SYSTEMENTWURF PR 1
This commit is contained in:
parent
0d1b73e3e0
commit
b57abbe1ac
@ -26,7 +26,37 @@ architecture rtl of rand is
|
||||
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;
|
||||
@ -46,11 +76,69 @@ begin
|
||||
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
|
||||
@ -65,9 +153,102 @@ begin
|
||||
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;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -28,9 +28,48 @@ architecture rtl of sine 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;
|
||||
signal index : integer range 1 to 1025;
|
||||
|
||||
--Signale anlegen:
|
||||
signal data_valid_intern : std_logic;
|
||||
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);
|
||||
signal count : INTEGER RANGE 1 TO 1025;
|
||||
|
||||
|
||||
|
||||
|
||||
type CalcState is(
|
||||
CALC_IDLE,
|
||||
CALC_ZUWEISEN,--1) dem IP-Core einen neuen angle Wert zuführen
|
||||
CALC_WARTEN,--2) warten bis dieser einen neuen Sinuswert berechnet hat
|
||||
--(dauert einige Takte - Hinweis result_valid und busy Signale des IP-Cores)
|
||||
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:
|
||||
u_float_sine: entity work.float_sine
|
||||
generic map (
|
||||
ITERATIONS => 8
|
||||
)
|
||||
port map (
|
||||
clk => clk,
|
||||
reset => reset,
|
||||
data_valid => data_valid_intern,
|
||||
angle => angle_intern,
|
||||
busy => busy_intern,
|
||||
result_valid => result_valid_intern,
|
||||
sine => sine_intern
|
||||
);
|
||||
|
||||
task_state_transitions : process ( current_task_state, task_start, index ) is
|
||||
begin
|
||||
next_task_state <= current_task_state;
|
||||
@ -40,7 +79,7 @@ begin
|
||||
next_task_state <= work.task.TASK_RUNNING;
|
||||
end if;
|
||||
when work.task.TASK_RUNNING =>
|
||||
if ( index = work.task.STREAM_LEN - 1 ) then
|
||||
if ( index = work.task.STREAM_LEN ) then
|
||||
next_task_state <= work.task.TASK_DONE;
|
||||
end if;
|
||||
when work.task.TASK_DONE =>
|
||||
@ -50,25 +89,88 @@ begin
|
||||
end case;
|
||||
end process task_state_transitions;
|
||||
|
||||
|
||||
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_ZUWEISEN;
|
||||
end if;
|
||||
when CALC_ZUWEISEN =>
|
||||
next_calc_state <= CALC_WARTEN;
|
||||
when CALC_WARTEN =>
|
||||
if(result_valid_intern = '1' and busy_intern = '0') then--busy_intern = '0'
|
||||
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_ZUWEISEN;
|
||||
|
||||
if(index = 1024) then
|
||||
next_calc_state <= CALC_IDLE;
|
||||
end if;
|
||||
end case;
|
||||
end process calc_state_transitions;
|
||||
|
||||
|
||||
sync : process ( clk, reset ) is
|
||||
|
||||
|
||||
VARIABLE sine_scaled : signed ( 31 downto 0 );
|
||||
|
||||
begin
|
||||
if ( reset = '1' ) then
|
||||
current_task_state <= work.task.TASK_IDLE;
|
||||
index <= 0;
|
||||
index <= 1;
|
||||
count <= 1;
|
||||
sine_scaled := (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;
|
||||
|
||||
--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');
|
||||
count <= 1;
|
||||
when CALC_ZUWEISEN =>
|
||||
--if(index > 1) then
|
||||
angle_intern <= angle_intern + signed(step_size);
|
||||
--end if;
|
||||
data_valid_intern <= '1';
|
||||
when CALC_WARTEN =>
|
||||
when CALC_SKALIEREN =>
|
||||
--if(result_valid_intern = '1') then
|
||||
sine_scaled := sine_intern;
|
||||
sine_scaled(30 downto 23) := sine_scaled(30 downto 23) + ( signed(amplitude(30 downto 23)) - 127);
|
||||
|
||||
--end if;
|
||||
when CALC_IN_FIFO_ABSPEICHERN =>
|
||||
|
||||
if(index > 1) then
|
||||
signal_writedata <= std_logic_vector(sine_scaled);
|
||||
end if;
|
||||
|
||||
signal_write <= '1';
|
||||
|
||||
index <= index + 1;
|
||||
count <= count + 1;
|
||||
end case;
|
||||
--E
|
||||
|
||||
end if;
|
||||
end process sync;
|
||||
|
||||
|
@ -3,10 +3,78 @@
|
||||
#include "system/data_channel.h"
|
||||
#include "system/float_word.h"
|
||||
|
||||
int task_rand_run( void * task ) {
|
||||
#include <stdio.h>
|
||||
|
||||
// TODO
|
||||
int task_rand_run( void * data )
|
||||
{
|
||||
|
||||
return 0;
|
||||
rand_config * task = ( rand_config * ) data;
|
||||
|
||||
|
||||
uint32_t data_channel_base = task->base.sink;
|
||||
|
||||
float seed = task->seed; //1.3
|
||||
float abs_min = task->abs_min; //0.125
|
||||
float abs_max = task->abs_max; //9.0
|
||||
|
||||
float_word random_number;
|
||||
random_number.value = seed;
|
||||
|
||||
uint32_t mask_bit_0 = 0x1;
|
||||
uint32_t mask_bit_1 = 0x2;
|
||||
uint32_t mask_bit_21 = 0x200000;
|
||||
uint32_t mask_bit_31 = 0x80000000;
|
||||
|
||||
uint32_t exponent = 0;
|
||||
uint32_t shifted_exponent = 0;
|
||||
uint32_t shifted = 0;
|
||||
uint32_t shifted_modifiziert = 0;
|
||||
|
||||
data_channel_clear( data_channel_base );
|
||||
|
||||
for(uint32_t i = 0; i < DATA_CHANNEL_DEPTH; ++i)
|
||||
{
|
||||
|
||||
//Bits extrahieren:
|
||||
uint32_t bit_0 = (random_number.word & mask_bit_0) >> 0;
|
||||
uint32_t bit_1 = (random_number.word & mask_bit_1) >> 1;
|
||||
uint32_t bit_21 = (random_number.word & mask_bit_21) >> 21;
|
||||
uint32_t bit_31 = (random_number.word & mask_bit_31) >> 31;
|
||||
|
||||
//XOR:
|
||||
uint32_t xor_result = bit_0 ^ bit_1 ^ bit_21 ^ bit_31;
|
||||
|
||||
//Shifted:
|
||||
shifted = random_number.word >> 1;
|
||||
|
||||
//shifted &= ~(0x80000000);
|
||||
shifted |= (xor_result << 31);
|
||||
|
||||
printf("%08x %08x %d \n", random_number.word, shifted, xor_result);
|
||||
|
||||
//Skalierung:
|
||||
#if 1
|
||||
exponent = (shifted >> 23) & 0xFF;
|
||||
if(exponent & (1 << 7)){
|
||||
exponent &= (0b10000001);
|
||||
}else{
|
||||
exponent |= (0b01111100);
|
||||
}
|
||||
|
||||
|
||||
shifted_modifiziert = shifted;
|
||||
shifted_exponent = exponent << 23;
|
||||
shifted_modifiziert &= 0x807FFFFF;
|
||||
shifted_modifiziert |= shifted_exponent;
|
||||
#endif
|
||||
|
||||
random_number.word = shifted_modifiziert;
|
||||
data_channel_write( data_channel_base, random_number.word );
|
||||
random_number.word = shifted;
|
||||
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2,9 +2,54 @@
|
||||
#include "system/data_channel.h"
|
||||
#include "system/float_word.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
int task_sine_run( void * data ) {
|
||||
|
||||
sine_config * task = ( sine_config * ) data;
|
||||
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
|
||||
uint32_t data_channel_base = task->base.sink;
|
||||
|
||||
uint32_t samples_per_periode = task->samples_per_periode;
|
||||
float phase = task->phase;
|
||||
float amplitude = task->amplitude;
|
||||
|
||||
|
||||
|
||||
data_channel_clear( data_channel_base );
|
||||
#if 0
|
||||
|
||||
for (uint32_t i = 0; i < (DATA_CHANNEL_DEPTH/samples_per_periode); ++i)
|
||||
{
|
||||
|
||||
for(uint32_t j = 0; j < (samples_per_periode); ++j)
|
||||
{
|
||||
|
||||
float_word res;
|
||||
res.value = amplitude * sin((2.0*M_PI/samples_per_periode) * j + phase);
|
||||
|
||||
|
||||
|
||||
data_channel_write( data_channel_base, res.word );
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
for (uint32_t i = 0; i < DATA_CHANNEL_DEPTH; ++i)
|
||||
{
|
||||
|
||||
float_word res;
|
||||
res.value = amplitude * sin((2.0*M_PI/samples_per_periode) * i + phase);
|
||||
|
||||
|
||||
|
||||
data_channel_write( data_channel_base, res.word );
|
||||
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user