diff --git a/hardware/signal_processing/.sine.vhd.swo b/hardware/signal_processing/.sine.vhd.swo new file mode 100644 index 0000000..950dda9 Binary files /dev/null and b/hardware/signal_processing/.sine.vhd.swo differ diff --git a/hardware/signal_processing/rand.vhd b/hardware/signal_processing/rand.vhd index 3a229f3..4eb0fb9 100644 --- a/hardware/signal_processing/rand.vhd +++ b/hardware/signal_processing/rand.vhd @@ -26,6 +26,19 @@ architecture rtl of rand is signal next_task_state : work.task.State; signal index : integer range 0 to work.task.STREAM_LEN; + type CalcState is ( + CALC_IDLE, + CALC_WRITE + ); + signal Calc_State : CalcState; + + signal lsfr : SIGNED( 31 downto 0 ); + signal lsfr_std_logic : std_logic_vector( 31 downto 0 ); + signal POLYNOM : std_logic_vector (31 downto 0); + + signal lsfr_dump : SIGNED( 31 downto 0 ); + + begin task_state_transitions : process ( current_task_state, task_start, index ) is begin @@ -50,17 +63,50 @@ begin begin if ( reset = '1' ) then current_task_state <= work.task.TASK_IDLE; + Calc_State <= CALC_IDLE; + lsfr <= SIGNED(seed); + lsfr_std_logic <= seed; + POLYNOM <= (others => '0'); + POLYNOM(31) <= '1'; + POLYNOM(21) <= '1'; + POLYNOM(1) <= '1'; + POLYNOM(0) <= '1'; 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; + lsfr <= SIGNED(seed); signal_write <= '0'; + when work.task.TASK_RUNNING => - index <= index + 1; - signal_write <= '1'; - signal_writedata <= ( others => '0' ); + case Calc_State is + when CALC_IDLE => + signal_write <= '0'; + lsfr_std_logic <= STD_LOGIC_VECTOR(lsfr); + if(lsfr_std_logic(0) = '1') then + lsfr <= SIGNED(lsfr_std_logic srl 1); + lsfr <= SIGNED(lsfr_std_logic XOR POLYNOM); + else + lsfr <= SIGNED(lsfr_std_logic srl 1); + end if; + lsfr <= SIGNED(lsfr_std_logic); + lsfr_dump <= lsfr; + + if(lsfr_std_logic(30) = '1') then + lsfr <= lsfr(31 downto 31) & "1000000" & lsfr(23 downto 0); + else + lsfr <= lsfr(31 downto 31) & "011111" & lsfr(24 downto 0); + end if; + Calc_State <= CALC_WRITE; + when CALC_WRITE => + signal_write <= '1'; + index <= index + 1; + Calc_State <= CALC_IDLE; + end case; + when work.task.TASK_DONE => index <= 0; signal_write <= '0'; @@ -69,5 +115,6 @@ begin end process sync; task_state <= current_task_state; + signal_writedata <= STD_LOGIC_VECTOR(lsfr); end architecture rtl; diff --git a/software/signal_processing/rand.c b/software/signal_processing/rand.c index d4fc0fd..93846ab 100644 --- a/software/signal_processing/rand.c +++ b/software/signal_processing/rand.c @@ -3,9 +3,72 @@ #include "system/data_channel.h" #include "system/float_word.h" -int task_rand_run( void * task ) { +#include "stdio.h" - // TODO +#define POLYNOM ((1 << 31)|(1 << 21)|(1 << 1)|(1 << 0)) + +int32_t shift_lsfr(int32_t *lsfr) { + int feedback; + + feedback = *lsfr & 1; + + *lsfr >>= 1; + + if(feedback == 1) + *lsfr ^= POLYNOM; + return *lsfr; + +} + +int32_t pot(int32_t base, int exp) { + int32_t res = 1; + while(exp-- >= 0) + res *= base; + + return res; +} + +uint8_t clamp_value(uint8_t value) { + + if(value & 128) { + value &= 0b10000001; + //value &= ((1 << 7) | (1 << 0)); + } else { + //value |= ~((1 << 1) | (1 << 0)); + value |= 0b01111100; + } + return value; + +} + +int task_rand_run( void * task ) { + + rand_config* config = ( rand_config* ) task; + float_word seed = { .value = config->seed }; + + uint32_t lfsr = seed.word; + + uint32_t data_channel_base = config->base.sink; + data_channel_clear(data_channel_base); + + for(uint32_t i = 0; i < DATA_CHANNEL_DEPTH; ++i) { + float_word res, value; + + //res.value = lfsr; + // + + + uint32_t E = (value.word >> 23) & 0xff; + E = clamp_value(E); + + res.word = value.word; + res.word &= ~(0xFF << 23); + res.word |= (E << 23); + + value.word = shift_lsfr(&lfsr) ; + + data_channel_write( data_channel_base, res.word); + } return 0; } diff --git a/software/signal_processing/system/task_rand.c b/software/signal_processing/system/task_rand.c index bc08f8b..7470197 100644 --- a/software/signal_processing/system/task_rand.c +++ b/software/signal_processing/system/task_rand.c @@ -21,7 +21,7 @@ rand_config RAND_CONFIG = { .cycle_count = 0 }, .seed = 1.3, .abs_min = 0.125, - .abs_max = 9.0 }; + .abs_max = 8.0 }; int task_rand_configure( void * data ) { rand_config * task = ( rand_config * ) data;