diff --git a/hardware/signal_processing/add.vhd b/hardware/signal_processing/add.vhd index 3e7315a..dfd42be 100644 --- a/hardware/signal_processing/add.vhd +++ b/hardware/signal_processing/add.vhd @@ -30,7 +30,35 @@ architecture rtl of add is signal next_task_state : work.task.State; signal index : integer range 0 to work.task.STREAM_LEN; -begin + signal float_add_start : std_logic := '0'; + signal float_add_done : std_logic; + signal float_add_a : std_logic_vector(31 downto 0); + signal float_add_b : std_logic_vector(31 downto 0); + signal float_add_sum : std_logic_vector(31 downto 0) := (others => '0'); + + type CalcState is ( + CALC_IDLE, + CALC_ADD, + CALC_STORE_RESULT + ); + signal current_calc_state : CalcState; + signal next_calc_state : CalcState; + + + begin + + u_float_add : entity work.float_add + port map( + clk => clk, + reset => reset, + start => float_add_start, + done => float_add_done, + A => float_add_a, + B => float_add_b, + sum => float_add_sum + ); + + task_state_transitions : process ( current_task_state, task_start, index ) is begin next_task_state <= current_task_state; @@ -50,28 +78,85 @@ begin end case; end process task_state_transitions; - sync : process ( clk, reset ) is + + calc_state_transistions : process (current_calc_state, current_task_state, float_add_done) 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_ADD; + end if; + when CALC_ADD => + if (float_add_done = '1') then + next_calc_state <= CALC_STORE_RESULT; + end if; + when CALC_STORE_RESULT => + next_calc_state <= CALC_IDLE; + end case; + end process calc_state_transistions; + + +-- Synchronisation: Task-State + task_sync : process (clk, reset) is begin - if ( reset = '1' ) then + if (reset = '1') then current_task_state <= work.task.TASK_IDLE; index <= 0; - elsif ( rising_edge( clk ) ) then + 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; + + if current_task_state = work.task.TASK_RUNNING then + -- Vorbereitung auf neue Berechnung + if index > 0 then + signal_a_read <= '1'; + signal_b_read <= '1'; + end if;--index <= index + 1; + else + signal_a_read <= '0'; + signal_b_read <= '0'; + --index <= 0; + end if; + + if current_calc_state = CALC_STORE_RESULT then + signal_a_read <= '0'; + signal_b_read <= '0'; signal_write <= '1'; - signal_writedata <= ( others => '0' ); - when work.task.TASK_DONE => - index <= 0; + signal_writedata <= float_add_sum; + index <= index + 1; + else signal_write <= '0'; + end if; + end if; + end process task_sync; + + -- Synchronisation: Calc-State + calc_sync : process (clk, reset) is + begin + if (reset = '1') then + current_calc_state <= CALC_IDLE; + float_add_start <= '0'; + float_add_a <= (others => '0'); + float_add_b <= (others => '0'); + elsif (rising_edge(clk)) then + current_calc_state <= next_calc_state; + + case current_calc_state is + when CALC_IDLE => + float_add_start <= '0'; + when CALC_ADD => + float_add_a <= signal_a_readdata; + float_add_b <= signal_b_readdata; + float_add_start <= '1'; + when CALC_STORE_RESULT => + float_add_start <= '0'; end case; end if; - end process sync; + end process calc_sync; task_state <= current_task_state; + end architecture rtl; diff --git a/hardware/signal_processing/rand.vhd b/hardware/signal_processing/rand.vhd index 3a229f3..1536034 100644 --- a/hardware/signal_processing/rand.vhd +++ b/hardware/signal_processing/rand.vhd @@ -1,73 +1,114 @@ -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; - -begin - 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; - - sync : process ( clk, reset ) is - begin - if ( reset = '1' ) then - current_task_state <= work.task.TASK_IDLE; - index <= 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; - end if; - end process sync; - - task_state <= current_task_state; - -end architecture rtl; +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 lfsr_reg : std_logic_vector(31 downto 0); + signal current_task_state : work.task.State; + signal next_task_state : work.task.State; + signal index : integer range 0 to work.task.STREAM_LEN; + +begin + + 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; + + + sync : process(clk, reset) is + variable random_value : std_logic_vector(31 downto 0); + variable lfsr_feedback : std_logic; + begin + if (reset = '1') then + current_task_state <= work.task.TASK_IDLE; + index <= 0; + lfsr_reg <= seed; + signal_write <= '0'; + elsif (rising_edge(clk)) then + + lfsr_feedback := lfsr_reg(31) xor lfsr_reg(21) xor lfsr_reg(1) xor lfsr_reg(0); + --lfsr_reg <= lfsr_feedback & lfsr_reg(31 downto 1); + + current_task_state <= next_task_state; + + case next_task_state is + when work.task.TASK_IDLE => + index <= 0; + signal_write <= '0'; + lfsr_reg <= seed; + + when work.task.TASK_RUNNING => + + lfsr_reg <= lfsr_feedback & lfsr_reg(31 downto 1); + random_value := lfsr_reg; + + + if random_value(30) = '1' then + + random_value(29 downto 24) := "000000"; -- Exponent 129 (2^3) + --random_value(6 downto 1) := (others => '0'); + random_value(23) := lfsr_reg(7); + end if; + if random_value(30) = '0' then + + random_value(29 downto 25) := "11111"; -- Exponent 123 (2^-3) + --random_value(6 downto 2) := (others => '1'); + random_value(24 downto 23) := lfsr_reg(5 downto 4); + end if; + + + random_value(31) := lfsr_reg(14); + + + signal_write <= '1'; + signal_writedata <= random_value; + + + --lfsr_reg <= lfsr_feedback & lfsr_reg(31 downto 1); + + + index <= index + 1; + + when work.task.TASK_DONE => + index <= 0; + signal_write <= '0'; + end case; + end if; + end process sync; + + task_state <= current_task_state; + +end architecture rtl; diff --git a/hardware/signal_processing/sine.vhd b/hardware/signal_processing/sine.vhd index 36fb916..fe5ff1a 100644 --- a/hardware/signal_processing/sine.vhd +++ b/hardware/signal_processing/sine.vhd @@ -30,8 +30,49 @@ architecture rtl of sine is signal next_task_state : work.task.State; signal index : integer range 0 to work.task.STREAM_LEN; + signal valid_gen : std_logic; + signal angle_gen : signed(31 downto 0); + signal busy_gen : std_logic; + signal result_valid_gen : std_logic; + signal sine_gen : signed(31 downto 0); + + signal sine_sign : std_logic; -- Vorzeichen + signal sine_exponent : signed(7 downto 0); -- Exponent + signal sine_mantissa : std_logic_vector(22 downto 0); -- Mantisse + signal scaled_exponent : signed(7 downto 0); -- Skalierter Exponent + signal scaled_sine : std_logic_vector(31 downto 0); -- Ergebnis + + + type CalcState is ( + CALC_IDLE, + CALC_GEN, + CALC_WAIT, + CALC_STORE, + CALC_STORE_RESULT + ); + + signal current_calc_state : CalcState; + signal next_calc_state : CalcState; + begin - task_state_transitions : process ( current_task_state, task_start, index ) is + + + u_float_sine : entity work.float_sine + generic map ( + ITERATIONS => 8 + ) + port map ( + clk => clk, + reset => reset, + data_valid => valid_gen, + angle => angle_gen, + busy => busy_gen, + result_valid => result_valid_gen, + sine => sine_gen + ); + + + task_state_transitions : process ( all ) is begin next_task_state <= current_task_state; case current_task_state is @@ -50,28 +91,96 @@ begin end case; end process task_state_transitions; + + calc_state_transistions : 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_GEN; + end if; + when CALC_GEN => + next_calc_state <= CALC_WAIT; + when CALC_WAIT => + next_calc_state <= CALC_STORE; + when CALC_STORE => + if result_valid_gen = '1' and busy_gen = '0' then + next_calc_state <= CALC_STORE_RESULT; + else + next_calc_state <= CALC_STORE; + end if; + when CALC_STORE_RESULT => + next_calc_state <= CALC_IDLE; + end case; + end process calc_state_transistions; + + + sync : process ( clk, reset ) is begin if ( reset = '1' ) then current_task_state <= work.task.TASK_IDLE; - index <= 0; + index <= 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; + if current_task_state = work.task.TASK_RUNNING then + end if; + + if current_calc_state = CALC_STORE_RESULT then + index <= index + 1; + + end if; end if; end process sync; + + sine_sign <= sine_gen(31); + sine_exponent <= signed(sine_gen(30 downto 23)); + sine_mantissa <= std_logic_vector(sine_gen(22 downto 0)); + + scaled_exponent <= sine_exponent + (signed(amplitude(30 downto 23)) - 127); + scaled_sine <= sine_sign & std_logic_vector(scaled_exponent) & sine_mantissa; + + + calc_sync : process ( clk, reset ) is + begin + if (reset = '1') then + current_calc_state <= CALC_IDLE; + valid_gen <= '0'; + angle_gen <= (others => '0'); + + signal_write <= '0'; + signal_writedata <= (others => '0'); + + elsif (rising_edge(clk)) then + current_calc_state <= next_calc_state; + signal_write <= '0'; + case current_calc_state is + when CALC_IDLE => + valid_gen <= '0'; + if current_task_state = work.task.TASK_IDLE then + angle_gen <= signed(phase); + end if; + when CALC_GEN => + if next_calc_state = CALC_WAIT then + valid_gen <= '1'; + + angle_gen <= angle_gen + signed(step_size); + end if; + when CALC_WAIT => + valid_gen <= '0'; + when CALC_STORE => + null; + when CALC_STORE_RESULT => + signal_write <= '1'; + signal_writedata <= scaled_sine; + + end case; + end if; + end process calc_sync; + task_state <= current_task_state; end architecture rtl; diff --git a/software/signal_processing/add.c b/software/signal_processing/add.c index c0be7d1..9164c34 100644 --- a/software/signal_processing/add.c +++ b/software/signal_processing/add.c @@ -4,7 +4,17 @@ int task_add_run( void * task ) { - // TODO + add_config * config = ( add_config * ) task; + + for ( uint32_t i = 0; i < DATA_CHANNEL_DEPTH; i++ ) { + float a; + float 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; } diff --git a/software/signal_processing/rand.c b/software/signal_processing/rand.c index d4fc0fd..737cd45 100644 --- a/software/signal_processing/rand.c +++ b/software/signal_processing/rand.c @@ -1,12 +1,45 @@ -#include "system/task_rand.h" -#include "system/hardware_task.h" -#include "system/data_channel.h" -#include "system/float_word.h" - -int task_rand_run( void * task ) { - - // TODO - - return 0; -} - +#include "system/task_rand.h" +#include "system/hardware_task.h" +#include "system/data_channel.h" +#include "system/float_word.h" +#include +#include + +int task_rand_run(void *task) { + rand_config *config = (rand_config *)task; + uint32_t data_channel_base = DATA_CHANNEL_2_BASE; + + + uint32_t lfsr = config->seed; + + for (uint32_t i = 0; i < DATA_CHANNEL_DEPTH; ++i) { + + uint32_t bit = ((lfsr >> 31) ^ (lfsr >> 21) ^ (lfsr >> 1) ^ (lfsr >> 0)) & 1; + lfsr = (lfsr << 1) | bit; + + + float_word res; + res.word = lfsr; + + + uint32_t exponent = (lfsr >> 23) & 0xFF; + + + if (exponent & 0x80) { + exponent = 0x80 | (lfsr & 0x01); + }else { + + exponent = 0x7C | (lfsr & 0x03); + } + + + res.word &= ~(0xFF << 23); + res.word |= (exponent << 23); + + + + data_channel_write(data_channel_base, res.word); + } + + return 0; +} diff --git a/software/signal_processing/sine.c b/software/signal_processing/sine.c index 3eb3ce5..de63315 100644 --- a/software/signal_processing/sine.c +++ b/software/signal_processing/sine.c @@ -1,10 +1,30 @@ #include "system/task_sine.h" +#include "system/hardware_task.h" +#include "system/sine_config.h" #include "system/data_channel.h" #include "system/float_word.h" +#include +#include +#include +#include + int task_sine_run( void * data ) { - // TODO + sine_config * task = ( sine_config * ) data; + uint32_t data_channel_base = task-> base.sink; + data_channel_clear( data_channel_base ); + + for ( uint32_t i = 0; i < DATA_CHANNEL_DEPTH; i++ ) { + + float_word res; + + for(uint32_t y = 0; y < task->samples_per_periode; y++) + { + res.value = task->amplitude * sin(2*3.14/task->samples_per_periode*y + task->phase); + data_channel_write( data_channel_base, res.word ); + } + } return 0; }