45 lines
1.5 KiB
C
45 lines
1.5 KiB
C
#include "system/task_rand.h"
|
|
#include "system/hardware_task.h"
|
|
#include "system/data_channel.h"
|
|
#include "system/float_word.h"
|
|
#include <stdio.h>
|
|
#include <system.h>
|
|
|
|
int task_rand_run( void * task ) {
|
|
|
|
rand_config * config = ( rand_config * ) task;
|
|
// seed auslesen (Startwert für Algorithmus)
|
|
float_word seed = { .value = config->seed };
|
|
// LFSR (linear feedback shift register)
|
|
uint32_t lfsr = seed.word;
|
|
|
|
for ( uint32_t i = 0; i < DATA_CHANNEL_DEPTH; ++i ) {
|
|
|
|
// LFSR Algorithmus
|
|
// Polynom: x^31 + x^21 + x^1 + 1
|
|
// Bits an Stellen 31, 21, 1 und 0 verknüpfen mit XOR
|
|
uint32_t bit = ((lfsr >> 31) ^ (lfsr >> 21) ^ (lfsr >> 1) ^ (lfsr >> 0)) & 1;
|
|
// Schiebe links und das neue Bit hinten anfügen
|
|
lfsr = (lfsr << 1) | bit;
|
|
|
|
// IEEE 754 Bit-Manipulation für Exponenten
|
|
float_word res;
|
|
res.word = lfsr;
|
|
// Prüfe Bit 30 (das höchste Bit des Exponenten 127 bias)
|
|
if ( res.word & (1 << 30) ) {
|
|
// Fall: Hoher Exponent -> Bits 29 bis 24 auf 0 setzen
|
|
// Das erzeugt Werte im Bereich um 2^2 (z.B. 4.0 bis 8.0)
|
|
res.word &= ~(0x3F << 24);
|
|
} else {
|
|
// Fall: Niedriger Exponent -> Bits 29 bis 25 auf 1 zwingen
|
|
// Das erzeugt Werte im Bereich um 2^-3 (z.B. 0.125)
|
|
res.word |= (0x1F << 25);
|
|
}
|
|
|
|
data_channel_write( config->base.sink, res.word );
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|