1010#include < gtest/gtest.h>
1111#include < M5Utility.hpp>
1212#include < M5Unified.hpp>
13+ #include < random>
1314
1415using namespace m5 ::utility;
1516
1617namespace {
18+ auto rng = std::default_random_engine{};
19+
20+ // x^16 + x^14 + x^13 + x^11 + 1
21+ uint32_t prng_successor32 (uint32_t x, uint32_t n)
22+ {
23+ while (n--) {
24+ // 0 16(32-16) 14(32-18) 13(32-19) 11(32-11)
25+ x = (x >> 1 ) | (((x >> 16 ) ^ (x >> 18 ) ^ (x >> 19 ) ^ (x >> 21 )) << 31 );
26+ }
27+ return x;
28+ }
29+
30+ uint16_t prng_successor16 (uint16_t x, uint32_t n)
31+ {
32+ while (n--) {
33+ // 0(16-16) 14(16-2) 13(16-3) 11(16-5)
34+ x = (x >> 1 ) | (((x >> 0 ) ^ (x >> 2 ) ^ (x >> 3 ) ^ (x >> 5 )) << 15 );
35+ }
36+ return x;
37+ }
38+
39+ } // namespace
40+
41+ TEST (Utility, FibonacciLFSR16)
42+ {
43+ {
44+ using LFSR16 = FibonacciLFSR_Right<16 , 16 , 14 , 13 , 11 >;
45+
46+ constexpr uint16_t seed{0xACE1U };
47+ LFSR16 lfsr{seed};
48+ // uint16_t reg = seed;
49+ // uint16_t bit;
50+ uint16_t p16 = seed;
51+ for (int i = 0 ; i < 65536 ; ++i) {
52+ p16 = prng_successor16 (p16, 1 );
53+ #if 0
54+ bool out = (reg >> 1);
55+ bit = (reg & 0x0001) ^ ((reg & 0x0004) >> 2) ^ ((reg & 0x0008) >> 3) ^ ((reg & 0x0020) >> 5);
56+ reg = (reg >> 1) | (bit << 15);
57+ #endif
58+ lfsr.step ();
59+ EXPECT_EQ (lfsr.value (), p16) << i;
60+ }
61+ }
1762}
1863
19- using FLL = FibonacciLFSR_Left<8 , 4 , 1 >; // Tapbit // bit 4,7
64+ TEST (Utility, FibonacciLFSR32)
65+ {
66+ {
67+ using LFSR32 = FibonacciLFSR_Right<32 , 16 , 14 , 13 , 11 >;
68+
69+ constexpr uint32_t seed{0xACE1U };
70+ LFSR32 lfsr{seed};
71+ uint32_t p32 = seed;
72+ for (int i = 0 ; i < 65536 ; ++i) {
73+ p32 = prng_successor32 (p32, 1 );
74+ lfsr.step ();
75+ EXPECT_EQ (lfsr.value (), p32) << i;
76+ }
77+ }
78+ }
79+
80+ using FLL = FibonacciLFSR_Left<8 , 8 , 5 >;
2081class DruagaLFSR : public FLL {
2182public:
2283 using Base = FLL;
@@ -25,14 +86,13 @@ class DruagaLFSR : public FLL {
2586
2687 bool step () noexcept
2788 {
28- const bool out = this ->_state .test (7 ); // MSB
29- const bool fb = !Base::taps_xor_all (this ->_state );
30- this ->_state <<= 1 ; // shift
31- this ->_state .set (0 , fb); // Insert into LSB
32- return out;
33- }
89+ const bool fb = !Base::taps_xor_all (this ->_state ); // NOT tap
90+ this ->_state <<= 1 ; // shift
91+ this ->_state .set (0 , fb); // Insert into LSB
92+ return fb;
93+ };
3494
35- uint64_t step (uint32_t nbits) noexcept
95+ uint64_t step (const uint32_t nbits) noexcept
3696 {
3797 uint64_t v{};
3898 for (uint32_t i = 0 ; i < nbits; ++i) v |= (uint64_t )step () << i;
@@ -65,35 +125,6 @@ class DruagaLFSR : public FLL {
65125 }
66126};
67127
68- TEST (Utility, FibonacciLFSR)
69- {
70- using LFSR16 = FibonacciLFSR_Right<16 , 16 , 14 , 13 , 11 >;
71-
72- LFSR16 l (0xACE1U );
73- uint16_t reg = 0xACE1 ;
74- uint16_t bit;
75- uint16_t first{};
76-
77- for (int i = 0 ; i < 65536 ; ++i) {
78- // bit 0, 2,3,5
79- // x^16 + x^(16-2) + x^(16-3) + x^(16-5) + 1
80- // x^16 + x^14 + x^13 + x^11 + 1
81- bit = (reg & 0x0001 ) ^ ((reg & 0x0004 ) >> 2 ) ^ ((reg & 0x0008 ) >> 3 ) ^ ((reg & 0x0020 ) >> 5 );
82- reg = (reg >> 1 ) | (bit << 15 );
83-
84- l.step ();
85- EXPECT_EQ (l.value (), reg);
86- // M5_LOGI("[%3d]:%04X:%04X", i, reg, (uint16_t)l.value());
87-
88- if (i == 0 ) {
89- first = reg;
90- }
91- if (i == 65535 ) {
92- EXPECT_EQ (reg, first);
93- }
94- }
95- }
96-
97128TEST (Utility, DruagaLFSR)
98129{
99130 { // 1 cycle
@@ -106,45 +137,45 @@ TEST(Utility, DruagaLFSR)
106137 EXPECT_EQ (d.next64 (), 0xFFFFFFFFFFFFFFFFull );
107138 }
108139
109- { // 217 cycle
140+ if ( 1 ) { // 217 cycle
110141 DruagaLFSR d (0 );
111142 std::vector<uint8_t > a1, a2;
112143
113144 for (int i = 0 ; i < 217 ; ++i) {
114145 d.step ();
115146 a1.push_back ((uint8_t )d.value ());
116- // M5_LOGI("[%3d]:%u", i, (uint8_t)d.value());
147+ // M5_LOGI("[%3d]:%u", i, (uint8_t)d.value());
117148 }
118149 for (int i = 0 ; i < 217 ; ++i) {
119150 d.step ();
120151 a2.push_back ((uint8_t )d.value ());
121- // M5_LOGI("[%3d]:%u", i, (uint8_t)d.value());
152+ // M5_LOGI("[%3d]:%u", i, (uint8_t)d.value());
122153 }
123154 // m5::utility::log::dump(a1.data(), a1.size(), false);
124155 // m5::utility::log::dump(a2.data(), a2.size(), false);
125156 EXPECT_EQ (a1, a2);
126157 }
127158
128- { // 31 cycle
159+ if ( 1 ) { // 31 cycle
129160 DruagaLFSR d (6 );
130161 std::vector<uint8_t > a1, a2;
131162
132163 for (int i = 0 ; i < 31 ; ++i) {
133164 d.step ();
134165 a1.push_back ((uint8_t )d.value ());
135- // M5_LOGI("[%3d]:%u", i, (uint8_t)d.value());
166+ // M5_LOGI("[%3d]:%u", i, (uint8_t)d.value());
136167 }
137168 for (int i = 0 ; i < 31 ; ++i) {
138169 d.step ();
139170 a2.push_back ((uint8_t )d.value ());
140- // M5_LOGI("[%3d]:%u", i, (uint8_t)d.value());
171+ // M5_LOGI("[%3d]:%u", i, (uint8_t)d.value());
141172 }
142173 // m5::utility::log::dump(a1.data(), a1.size(), false);
143174 // m5::utility::log::dump(a2.data(), a2.size(), false);
144175 EXPECT_EQ (a1, a2);
145176 }
146177
147- { // 7 cycle
178+ if ( 1 ) { // 7 cycle
148179 DruagaLFSR d (26 );
149180 std::vector<uint8_t > a1, a2;
150181
0 commit comments