diff --git a/hardware/signal_processing/add.vhd b/hardware/signal_processing/add.vhd index 3e7315a..9e8cc13 100644 --- a/hardware/signal_processing/add.vhd +++ b/hardware/signal_processing/add.vhd @@ -6,6 +6,7 @@ library work; use work.reg32.all; use work.task.all; +-- Anlegen der Variablen des Programms entity add is port ( clk : in std_logic; @@ -25,12 +26,30 @@ entity add is ); end entity add; +-- Signale anlegen architecture rtl of add 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_run :integer range 0 to 2; + signal start_value : std_logic; + signal done_value : std_logic; + signal write_value : std_logic_vector( 31 downto 0 ); begin + -- Instanziierung der float_add.vhd + u_float_add : entity work.float_add + port map( + clk => clk, + reset => reset, + start => start_value, + done => done_value, + a => signal_a_readdata, + b => signal_b_readdata, + sum => write_value + ); + + -- Zustandsautomat fuer die Zustandsswechsel task_state_transitions : process ( current_task_state, task_start, index ) is begin next_task_state <= current_task_state; @@ -40,7 +59,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,24 +69,55 @@ begin end case; end process task_state_transitions; + -- Zustandautomat fuer die Berechnung sync : process ( clk, reset ) is begin if ( reset = '1' ) then current_task_state <= work.task.TASK_IDLE; index <= 0; + -- alle Signale in der Reset Bedingung initialisieren + start_value <= '0'; + signal_a_read <= '0'; + signal_b_read <= '0'; + signal_write <= '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'; + -- idle + when work.task.TASK_IDLE => + index <= 0; + signal_write <= '0'; + -- running + when work.task.TASK_RUNNING => + case index_run is + + when 0 => + signal_writedata <= ( others => '0' ); + start_value <= '1'; + index_run <= index_run + 1; + + when 1 => + if(done_value = '1') then + start_value <= '0'; + + signal_write <= '1'; + signal_writedata <= write_value; + + signal_a_read <= '1'; + signal_b_read <= '1'; + + index_run <= index_run + 1; + end if; + when 2 => + signal_write <= '0'; + signal_a_read <= '0'; + signal_b_read <= '0'; + index_run <= 0; + index <= index + 1; + end case; + -- done + when work.task.TASK_DONE => + index <= 0; end case; end if; end process sync; diff --git a/hardware/signal_processing/rand.vhd b/hardware/signal_processing/rand.vhd index 3a229f3..4336fee 100644 --- a/hardware/signal_processing/rand.vhd +++ b/hardware/signal_processing/rand.vhd @@ -25,6 +25,11 @@ 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; + signal lfsr : std_logic_vector( 31 downto 0 ); + signal lfsr_next : std_logic_vector( 31 downto 0 ); + signal bitte : std_logic; + signal exponent : std_logic_vector( 7 downto 0 ); + signal ieee754 : std_logic_vector( 31 downto 0 ); begin task_state_transitions : process ( current_task_state, task_start, index ) is @@ -46,24 +51,39 @@ begin end case; end process task_state_transitions; + exponent <= std_logic_vector(to_unsigned(128, 8) + unsigned(lfsr(23 downto 23))) when (lfsr(30) = '1') + else std_logic_vector(to_unsigned(124, 8) + unsigned(lfsr(24 downto 23))); + + ieee754 <= lfsr(31) & exponent(7 downto 0) & lfsr(22 downto 0); + + bitte <= (lfsr(31) XOR lfsr(21) XOR lfsr(1)); + lfsr_next <= lfsr(30 downto 0) & bitte; + sync : process ( clk, reset ) is begin if ( reset = '1' ) then current_task_state <= work.task.TASK_IDLE; index <= 0; + -- alle Signale in der Reset Bedingung initialisieren + lfsr <= seed; 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'; + when work.task.TASK_IDLE => + index <= 0; + signal_write <= '0'; + + lfsr <= seed; + when work.task.TASK_RUNNING => + signal_write <= '1'; + signal_writedata <= ( ieee754 ); + + lfsr <= lfsr_next; + index <= index + 1; + + when work.task.TASK_DONE => + index <= 0; + signal_write <= '0'; end case; end if; end process sync; diff --git a/hardware/signal_processing/sine.vhd b/hardware/signal_processing/sine.vhd index 36fb916..1dacf23 100644 --- a/hardware/signal_processing/sine.vhd +++ b/hardware/signal_processing/sine.vhd @@ -29,8 +29,31 @@ 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_run :integer range 0 to 2; + signal data_valid : std_logic; + signal busy : std_logic; + signal result_valid : std_logic; + signal angle : signed(31 downto 0); + signal write_value : signed(31 downto 0); begin + -- Instanziierung der float_sine.vhd + u_float_sine : entity work.float_sine + generic map( + ITERATIONS => 8 + ) + port map( + clk => clk, + reset => reset, + + data_valid => data_valid, + busy => busy, + result_valid => result_valid, + angle => angle, + sine => write_value + ); + + -- Zustandsautomat fuer die Zustandsswechsel task_state_transitions : process ( current_task_state, task_start, index ) is begin next_task_state <= current_task_state; @@ -40,7 +63,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 -- - 1 ) then next_task_state <= work.task.TASK_DONE; end if; when work.task.TASK_DONE => @@ -50,24 +73,49 @@ begin end case; end process task_state_transitions; + -- Zustandautomat fuer die Berechnung sync : process ( clk, reset ) is begin if ( reset = '1' ) then current_task_state <= work.task.TASK_IDLE; index <= 0; + -- alle Signale in der Reset Bedingung initialisieren + data_valid <= '0'; + signal_write <= '0'; + angle <= x"00000000"; 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'; + -- idle + when work.task.TASK_IDLE => + index <= 0; + signal_write <= '0'; + -- running + when work.task.TASK_RUNNING => + case index_run is + when 0 => + signal_write <= '0'; + angle <= angle + signed(step_size);--signed(phase) + data_valid <= '1'; + + index_run <= index_run + 1; + when 1 => + data_valid <= '0'; + if(result_valid = '1') then + signal_write <= '1'; + signal_writedata <= std_logic_vector(write_value); + + index_run <= index_run + 1; + end if; + when 2 => + signal_write <= '0'; + index_run <= 0; + index <= index + 1; + end case; + -- done + when work.task.TASK_DONE => + index <= 0; + signal_write <= '0'; end case; end if; end process sync; diff --git a/software/signal_processing/add.c b/software/signal_processing/add.c index c0be7d1..243d1e4 100644 --- a/software/signal_processing/add.c +++ b/software/signal_processing/add.c @@ -2,10 +2,23 @@ #include "system/data_channel.h" #include "system/float_word.h" -int task_add_run( void * task ) { +int task_add_run( void * task ) +{ + add_config * config = (add_config * ) task; - // TODO + // Nachfolgende Antworten Lesen den FIFO der ersten und zweiten Datenquelle aus + // den jeweils gelesenen Wert mit 4 und speichern das Ergebnis in der Datensenke + for (uint32_t i = 0; i < DATA_CHANNEL_DEPTH; ++i) + { + float a, b; + data_channel_read( config->sources[0], (uint32_t *) & a ); + data_channel_read( config->sources[1], (uint32_t *) & b ); + + float_word c; + c.value = a + b; + data_channel_write( config->sink, c.word ); + } + + return 0; - return 0; } - diff --git a/software/signal_processing/rand.c b/software/signal_processing/rand.c index d4fc0fd..2e8cb99 100644 --- a/software/signal_processing/rand.c +++ b/software/signal_processing/rand.c @@ -2,11 +2,43 @@ #include "system/hardware_task.h" #include "system/data_channel.h" #include "system/float_word.h" +#include +#include int task_rand_run( void * task ) { - // TODO + // Nachfolgende Anweisungen Schreiben 1024 Mal den seed Wert in den FIFO für Rand + rand_config * config = ( rand_config * ) task; + float_word seed = {.value = config->seed}; - return 0; + uint32_t lfsr = seed.word; + uint32_t bit = 0; // Must be 32-bit to allow bit << 31 later in the code + + for( uint32_t i = 0; i < DATA_CHANNEL_DEPTH; i++ ) { + float_word res; + + uint32_t sign = (lfsr >> 31) & 1; + uint32_t exponent; + uint32_t mantisse = lfsr & 0x7FFFFF; + + if((lfsr >> 30) & 1) // MSB exponent + { + exponent = 128 + ((lfsr >> 23) & 1); // 128 to 129 + } + else + { + exponent = 124 + ((lfsr >> 23) & 3); // 124 to 127 + } + + uint32_t ieee754 = (sign << 31) | (exponent << 23) | mantisse; + res.value = ieee754; + + data_channel_write( config->base.sink, ieee754); + + // fibonacci feedback polynomial: x^31 + x^21 + x^1 + 1 + bit = ((lfsr >> 31) ^ (lfsr >> 21) ^ (lfsr >> 1)) & 1; + lfsr = (lfsr << 1) | bit; + } + + return 0; } - diff --git a/software/signal_processing/sine.c b/software/signal_processing/sine.c index 3eb3ce5..68da65a 100644 --- a/software/signal_processing/sine.c +++ b/software/signal_processing/sine.c @@ -1,10 +1,21 @@ #include "system/task_sine.h" #include "system/data_channel.h" #include "system/float_word.h" +#include int task_sine_run( void * data ) { - // TODO + // Nachfolgende Anweisungen Schreiben 1024 Mal den Wert 4 in den FIFO für Sinus + sine_config * task = ( sine_config * ) data; + uint32_t data_channel_base = task->base.sink; + data_channel_clear( data_channel_base ); - return 0; + for( uint32_t i = 0; i < DATA_CHANNEL_DEPTH; i++ ) { + float_word res; + res.value = task->amplitude * sin((2 * M_PI / task->samples_per_periode) * i + task->phase ); + + data_channel_write( data_channel_base, res.word ); + } + + return 0; }