Compare commits
No commits in common. "9f5c69c9cc353cb75c809c998ea12b5b9e369269" and "09beb03631aea6ba91fbc65aaf20e3f7cd046b86" have entirely different histories.
9f5c69c9cc
...
09beb03631
97
README.txt
97
README.txt
|
@ -16,55 +16,21 @@ These PRNGs are a good alternative to linear feedback shift registers (LFSR).
|
||||||
Although LFSRs are commonly used, their output exhibits strong correlations.
|
Although LFSRs are commonly used, their output exhibits strong correlations.
|
||||||
Furthermore, correctly generating multi-bit random words with LFSRs is tricky.
|
Furthermore, correctly generating multi-bit random words with LFSRs is tricky.
|
||||||
|
|
||||||
NOTE: This library is not designed for cryptographic applications
|
NOTE: None of the RNGs in this package are cryptographic random number
|
||||||
(such as generating passwords, encryption keys).
|
generators. These generators are not suitable for cryptography.
|
||||||
Most of the RNGs in this library are cryptographically weak.
|
|
||||||
|
|
||||||
|
|
||||||
Xoshiro128++ RNG
|
|
||||||
----------------
|
|
||||||
|
|
||||||
Xoshiro128++ is a random number generator developed in 2019 by
|
|
||||||
David Blackman and Sebastiano Vigna. The Xoshiro construction is
|
|
||||||
based on the Xorshift concept invented by George Marsaglia.
|
|
||||||
|
|
||||||
See also http://prng.di.unimi.it/
|
|
||||||
|
|
||||||
This RNG produces a sequence of 32-bit words. It passes all known
|
|
||||||
statistical tests and has a relatively long period (2**128 - 1).
|
|
||||||
|
|
||||||
The VHDL implementation produces 32 new random bits on every (enabled)
|
|
||||||
clock cycle. It is quite efficient in terms of FPGA resources, but it
|
|
||||||
requires two cascaded 32-bit adders which limit its speed. An optional
|
|
||||||
pipeline stage can be inserted between the adders to improve the timing
|
|
||||||
performance of the circuit.
|
|
||||||
|
|
||||||
Output word length: 32 bits
|
|
||||||
Seed length: 128 bits
|
|
||||||
Period: 2**128 - 1
|
|
||||||
|
|
||||||
FPGA resources: general logic and two 32-bit adders
|
|
||||||
Synthesis results: 201 LUTs, 194 registers on Spartan-6
|
|
||||||
149 LUTs, 194 registers on Spartan-7
|
|
||||||
Timing results: 400 MHz on Spartan-6 LX45-3
|
|
||||||
350 MHz on Spartan-7 S25-1
|
|
||||||
|
|
||||||
|
|
||||||
Xoroshiro128+ RNG
|
Xoroshiro128+ RNG
|
||||||
-----------------
|
------------------
|
||||||
|
|
||||||
Xoroshiro128+ is an RNG algorithm developed in 2016 by David Blackman
|
Xoroshiro128+ is an RNG algorithm developed in 2016 by David Blackman
|
||||||
and Sebastiano Vigna. The VHDL code matches an updated version of
|
and Sebastiano Vigna. It is a further development of the Xorshift algorithm
|
||||||
the algorithm called "xoroshiro128+ 1.0", released in 2018.
|
invented by George Marsaglia
|
||||||
The Xoroshiro algorithm is based on the Xorshift concept invented
|
|
||||||
by George Marsaglia.
|
|
||||||
|
|
||||||
See also http://prng.di.unimi.it/
|
See also http://xoroshiro.di.unimi.it/
|
||||||
|
|
||||||
This RNG passes many statistical tests, but the least significant
|
This RNG passes many statistical tests. Its period, 2**128 - 1, is long
|
||||||
output bits are known to be not fully random and fail certain tests.
|
compared to a typical LFSR, but much shorter than the Mersenne Twister.
|
||||||
The generator has a long period (2**128 - 1) compared to a typical LFSR,
|
|
||||||
but much shorter than the Mersenne Twister.
|
|
||||||
The output is 1-dimensionally equidistributed.
|
The output is 1-dimensionally equidistributed.
|
||||||
|
|
||||||
The VHDL implementation produces 64 new random bits on every (enabled)
|
The VHDL implementation produces 64 new random bits on every (enabled)
|
||||||
|
@ -76,7 +42,7 @@ Seed length: 128 bits
|
||||||
Period: 2**128 - 1
|
Period: 2**128 - 1
|
||||||
|
|
||||||
FPGA resources: general logic and 64-bit adder
|
FPGA resources: general logic and 64-bit adder
|
||||||
Synthesis results: 198 LUTs, 193 registers on Spartan-6
|
Sythesis results: 194 LUTs, 192 registers on Spartan-6
|
||||||
Timing results: 333 MHz on Spartan-6 LX45-3
|
Timing results: 333 MHz on Spartan-6 LX45-3
|
||||||
|
|
||||||
|
|
||||||
|
@ -113,62 +79,21 @@ Seed length: 32 bits
|
||||||
Period: 2**19937 - 1
|
Period: 2**19937 - 1
|
||||||
|
|
||||||
FPGA resources: RAM block, 32 bits x 1024 elements
|
FPGA resources: RAM block, 32 bits x 1024 elements
|
||||||
Synthesis results: 279 LUTs, 297 registers, 2x RAMB16 on Spartan-6
|
Sythesis results: 279 LUTs, 297 registers, 2x RAMB16 on Spartan-6
|
||||||
Timing results: 300 MHz on Spartan-6 LX45-3
|
Timing results: 300 MHz on Spartan-6 LX45-3
|
||||||
|
|
||||||
|
|
||||||
Trivium RNG
|
|
||||||
-----------
|
|
||||||
|
|
||||||
Trivium is a stream cipher published in 2005 by Christophe De Canniere
|
|
||||||
and Bart Preneel as part of the eSTREAM project.
|
|
||||||
|
|
||||||
See also C. De Canniere, B. Preneel, "Trivium Specifications",
|
|
||||||
http://www.ecrypt.eu.org/stream/p3ciphers/trivium/trivium_p3.pdf
|
|
||||||
|
|
||||||
See also the eSTREAM portfolio page for Trivium:
|
|
||||||
http://www.ecrypt.eu.org/stream/e2-trivium.html
|
|
||||||
|
|
||||||
This library uses the key stream of the Trivium cipher as a sequence
|
|
||||||
of random bits. The VHDL implementation produces up to 64 new random bits
|
|
||||||
on every (enabled) clock cycle. The number of bits per clock cycle is
|
|
||||||
configurade as a synthesis parameter.
|
|
||||||
|
|
||||||
This RNG passes all known statistical tests. However, little is known
|
|
||||||
about its period. The period depends on the seed value, and is believed
|
|
||||||
to be long (at least 2**80) for the vast majority of seed choices.
|
|
||||||
|
|
||||||
After reset and after each reseeding, the RNG must process 1152 bits
|
|
||||||
to initialize its state. This takes up to 1152 clock cycles, depending
|
|
||||||
on the configured number of bits per cycle. The RNG can not provide random
|
|
||||||
data during this time.
|
|
||||||
|
|
||||||
Output word length: configurable from 1 to 64 bits (must be power-of-2)
|
|
||||||
Seed length: 80 bits key + 80 bits IV
|
|
||||||
Period: unknown, depends on seed
|
|
||||||
|
|
||||||
FPGA resources: only general logic (AND, XOR ports, registers)
|
|
||||||
Synthesis results: 202 LUTs, 332 registers on Spartan-6 (32 bits output)
|
|
||||||
145 LUTs, 332 registers on Spartan-7 (32 bits output)
|
|
||||||
Timing results: 380 MHz on Spartan-6 LX45-3 (32 bits output)
|
|
||||||
440 MHz on Spartan-7 S25-1 (32 bits output)
|
|
||||||
|
|
||||||
|
|
||||||
Code organization
|
Code organization
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
rtl/ Synthesizable VHDL code
|
rtl/ Synthesizable VHDL code
|
||||||
rtl/rng_xoshiro128plusplus.vhdl Implementation of Xoshiro128++ RNG
|
|
||||||
rtl/rng_xoroshiro128plus.vhdl Implementation of Xoroshiro128+ RNG
|
rtl/rng_xoroshiro128plus.vhdl Implementation of Xoroshiro128+ RNG
|
||||||
rtl/rng_mt19937.vhdl Implementation of Mersenne Twister RNG
|
rtl/rng_mt19937.vhdl Implementation of Mersenne Twister RNG
|
||||||
rtl/rng_trivium.vhdl Implementation of Trivium RNG
|
|
||||||
|
|
||||||
sim/ Test benches
|
sim/ Test benches
|
||||||
sim/Makefile Makefile for building test benches with GHDL
|
sim/Makefile Makefile for building test benches with GHDL
|
||||||
sim/tb_xoshiro128plusplus.vhdl Test bench for Xoshiro128++ RNG
|
|
||||||
sim/tb_xoroshiro128plus.vhdl Test bench for Xoroshiro128+ RNG
|
sim/tb_xoroshiro128plus.vhdl Test bench for Xoroshiro128+ RNG
|
||||||
sim/tb_mt19937.vhdl Test bench for Mersenne Twister RNG
|
sim/tb_mt19937.vhdl Test bench for Mersenne Twister RNG
|
||||||
sim/tb_trivium.vhdl Test bench for Trivium RNG
|
|
||||||
|
|
||||||
refimpl/ Reference software implementations of RNGs
|
refimpl/ Reference software implementations of RNGs
|
||||||
|
|
||||||
|
@ -178,7 +103,7 @@ Timing results: 380 MHz on Spartan-6 LX45-3 (32 bits output)
|
||||||
License
|
License
|
||||||
-------
|
-------
|
||||||
|
|
||||||
Copyright (C) 2016-2020 Joris van Rantwijk
|
Copyright (C) 2016 Joris van Rantwijk
|
||||||
|
|
||||||
This VHDL library is free software; you can redistribute it and/or
|
This VHDL library is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU Lesser General Public License
|
modify it under the terms of the GNU Lesser General Public License
|
||||||
|
|
|
@ -4,28 +4,19 @@
|
||||||
# This makefile works with GCC under Linux.
|
# This makefile works with GCC under Linux.
|
||||||
#
|
#
|
||||||
|
|
||||||
CC = gcc
|
|
||||||
CXX = g++
|
|
||||||
CFLAGS = -std=c11 -Wall -O2
|
|
||||||
CXXFLAGS = -std=c++11 -Wall -O2
|
|
||||||
|
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
all: ref_xoshiro128plusplus \
|
all: ref_xoroshiro ref_mt19937 ref_trivium
|
||||||
ref_xoroshiro128plus \
|
|
||||||
ref_mt19937 \
|
|
||||||
ref_trivium
|
|
||||||
|
|
||||||
ref_xoshiro128plusplus: ref_xoshiro128plusplus.c
|
ref_xoroshiro: ref_xoroshiro.c
|
||||||
ref_xoroshiro128plus: ref_xoroshiro128plus.c
|
$(CC) -std=c11 -Wall -O2 -o $@ $<
|
||||||
|
|
||||||
ref_mt19937: ref_mt19937.cpp
|
ref_mt19937: ref_mt19937.cpp
|
||||||
|
$(CXX) -std=c++11 -Wall -O2 -o $@ $<
|
||||||
|
|
||||||
ref_trivium: ref_trivium.cpp
|
ref_trivium: ref_trivium.cpp
|
||||||
|
$(CXX) -std=c++11 -Wall -O2 -o $@ $<
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
$(RM) ref_xoshiro128plusplus
|
$(RM) ref_xoroshiro ref_mt19937 ref_trivium
|
||||||
$(RM) ref_xoroshiro128plus
|
|
||||||
$(RM) ref_mt19937
|
|
||||||
$(RM) ref_trivium
|
|
||||||
|
|
||||||
|
|
|
@ -13,13 +13,14 @@
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
/* ========== BEGIN of reference implementation of xoroshiro128+ ==========
|
/* ========== BEGIN of reference implementation of xoroshiro128+ ==========
|
||||||
* Source: http://prng.di.unimi.it/
|
* Source: http://xoroshiro.di.unimi.it/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Written in 2016-2018 by David Blackman and Sebastiano Vigna (vigna@acm.org)
|
/* Written in 2016 by David Blackman and Sebastiano Vigna (vigna@acm.org)
|
||||||
|
|
||||||
To the extent possible under law, the author has dedicated all copyright
|
To the extent possible under law, the author has dedicated all copyright
|
||||||
and related and neighboring rights to this software to the public domain
|
and related and neighboring rights to this software to the public domain
|
||||||
|
@ -27,46 +28,20 @@ worldwide. This software is distributed without any warranty.
|
||||||
|
|
||||||
See <http://creativecommons.org/publicdomain/zero/1.0/>. */
|
See <http://creativecommons.org/publicdomain/zero/1.0/>. */
|
||||||
|
|
||||||
#include <stdint.h>
|
int64_t s[2];
|
||||||
|
|
||||||
/* This is xoroshiro128+ 1.0, our best and fastest small-state generator
|
|
||||||
for floating-point numbers. We suggest to use its upper bits for
|
|
||||||
floating-point generation, as it is slightly faster than
|
|
||||||
xoroshiro128++/xoroshiro128**. It passes all tests we are aware of
|
|
||||||
except for the four lower bits, which might fail linearity tests (and
|
|
||||||
just those), so if low linear complexity is not considered an issue (as
|
|
||||||
it is usually the case) it can be used to generate 64-bit outputs, too;
|
|
||||||
moreover, this generator has a very mild Hamming-weight dependency
|
|
||||||
making our test (http://prng.di.unimi.it/hwd.php) fail after 5 TB of
|
|
||||||
output; we believe this slight bias cannot affect any application. If
|
|
||||||
you are concerned, use xoroshiro128++, xoroshiro128** or xoshiro256+.
|
|
||||||
|
|
||||||
We suggest to use a sign test to extract a random Boolean value, and
|
|
||||||
right shifts to extract subsets of bits.
|
|
||||||
|
|
||||||
The state must be seeded so that it is not everywhere zero. If you have
|
|
||||||
a 64-bit seed, we suggest to seed a splitmix64 generator and use its
|
|
||||||
output to fill s.
|
|
||||||
|
|
||||||
NOTE: the parameters (a=24, b=16, b=37) of this version give slightly
|
|
||||||
better results in our test than the 2016 version (a=55, b=14, c=36).
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline uint64_t rotl(const uint64_t x, int k) {
|
static inline uint64_t rotl(const uint64_t x, int k) {
|
||||||
return (x << k) | (x >> (64 - k));
|
return (x << k) | (x >> (64 - k));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint64_t s[2];
|
|
||||||
|
|
||||||
uint64_t next(void) {
|
uint64_t next(void) {
|
||||||
const uint64_t s0 = s[0];
|
const uint64_t s0 = s[0];
|
||||||
uint64_t s1 = s[1];
|
uint64_t s1 = s[1];
|
||||||
const uint64_t result = s0 + s1;
|
const uint64_t result = s0 + s1;
|
||||||
|
|
||||||
s1 ^= s0;
|
s1 ^= s0;
|
||||||
s[0] = rotl(s0, 24) ^ s1 ^ (s1 << 16); // a, b
|
s[0] = rotl(s0, 55) ^ s1 ^ (s1 << 14); // a, b
|
||||||
s[1] = rotl(s1, 37); // c
|
s[1] = rotl(s1, 36); // c
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -83,12 +58,12 @@ int main(int argc, const char **argv)
|
||||||
if (argc != 4) {
|
if (argc != 4) {
|
||||||
fprintf(stderr, "Reference implementation of RNG xoroshiro128+\n");
|
fprintf(stderr, "Reference implementation of RNG xoroshiro128+\n");
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
fprintf(stderr, "Usage: ref_xoroshiro128plus SEED0 SEED1 NUMVALUE\n");
|
fprintf(stderr, "Usage: ref_xoroshiro SEED0 SEED1 NUMVALUE\n");
|
||||||
fprintf(stderr, " SEED0 seed value in range 0 .. (2**64-1)\n");
|
fprintf(stderr, " SEED0 seed value in range 0 .. (2**64-1)\n");
|
||||||
fprintf(stderr, " SEED1 seed value in range 0 .. (2**64-1)\n");
|
fprintf(stderr, " SEED1 seed value in range 0 .. (2**64-1)\n");
|
||||||
fprintf(stderr, " NUMVALUE number of values to get from generator\n");
|
fprintf(stderr, " NUMVALUE number of values to get from generator\n");
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
fprintf(stderr, "Example: ref_xoroshiro128plus 0x3141592653589793 "
|
fprintf(stderr, "Example: ref_xoroshiro 0x3141592653589793 "
|
||||||
"0x0123456789abcdef 100\n");
|
"0x0123456789abcdef 100\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
|
@ -1,119 +0,0 @@
|
||||||
/*
|
|
||||||
* Reference implementation of "xoshiro128++" in C.
|
|
||||||
*
|
|
||||||
* Algorithm code by David Blackman and Sebastiano Vigna <vigna@acm.org>
|
|
||||||
* Main program wrapper by Joris van Rantwijk <joris@jorisvr.nl>
|
|
||||||
*
|
|
||||||
* To the extent possible under law, the author has dedicated all copyright
|
|
||||||
* and related and neighboring rights to this software to the public domain
|
|
||||||
* worldwide. This software is distributed without any warranty.
|
|
||||||
*
|
|
||||||
* See <http://creativecommons.org/publicdomain/zero/1.0/>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
|
|
||||||
/* ========== BEGIN of reference implementation of xoshiro128++ ==========
|
|
||||||
* Source: http://prng.di.unimi.it/
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Written in 2019 by David Blackman and Sebastiano Vigna (vigna@acm.org)
|
|
||||||
|
|
||||||
To the extent possible under law, the author has dedicated all copyright
|
|
||||||
and related and neighboring rights to this software to the public domain
|
|
||||||
worldwide. This software is distributed without any warranty.
|
|
||||||
|
|
||||||
See <http://creativecommons.org/publicdomain/zero/1.0/>. */
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
/* This is xoshiro128++ 1.0, one of our 32-bit all-purpose, rock-solid
|
|
||||||
generators. It has excellent speed, a state size (128 bits) that is
|
|
||||||
large enough for mild parallelism, and it passes all tests we are aware
|
|
||||||
of.
|
|
||||||
|
|
||||||
For generating just single-precision (i.e., 32-bit) floating-point
|
|
||||||
numbers, xoshiro128+ is even faster.
|
|
||||||
|
|
||||||
The state must be seeded so that it is not everywhere zero. */
|
|
||||||
|
|
||||||
|
|
||||||
static inline uint32_t rotl(const uint32_t x, int k) {
|
|
||||||
return (x << k) | (x >> (32 - k));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static uint32_t s[4];
|
|
||||||
|
|
||||||
uint32_t next(void) {
|
|
||||||
const uint32_t result = rotl(s[0] + s[3], 7) + s[0];
|
|
||||||
|
|
||||||
const uint32_t t = s[1] << 9;
|
|
||||||
|
|
||||||
s[2] ^= s[0];
|
|
||||||
s[3] ^= s[1];
|
|
||||||
s[1] ^= s[2];
|
|
||||||
s[0] ^= s[3];
|
|
||||||
|
|
||||||
s[2] ^= t;
|
|
||||||
|
|
||||||
s[3] = rotl(s[3], 11);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ========== END of reference implementation of xoshiro128++ ========== */
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, const char **argv)
|
|
||||||
{
|
|
||||||
char *p;
|
|
||||||
unsigned long numval;
|
|
||||||
unsigned long k;
|
|
||||||
unsigned long long seed_tmp;
|
|
||||||
|
|
||||||
if (argc != 4) {
|
|
||||||
fprintf(stderr, "Reference implementation of RNG xoshiro128++\n");
|
|
||||||
fprintf(stderr, "\n");
|
|
||||||
fprintf(stderr, "Usage: ref_xoshiro128plusplus SEED0 SEED1 NVALUE\n");
|
|
||||||
fprintf(stderr, " SEEDn seed value in range 0 .. (2**64-1)\n");
|
|
||||||
fprintf(stderr, " NVALUE number of values to get from generator\n");
|
|
||||||
fprintf(stderr, "\n");
|
|
||||||
fprintf(stderr, "Example: ref_xoshiro128plusplus 0x3141592653589793 "
|
|
||||||
"0x0123456789abcdef 100\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
seed_tmp = strtoull(argv[1], &p, 0);
|
|
||||||
if (p == argv[1] || *p != '\0') {
|
|
||||||
fprintf(stderr, "ERROR: Invalid value for SEED0\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
s[0] = (uint32_t)seed_tmp;
|
|
||||||
s[1] = (uint32_t)(seed_tmp >> 32);
|
|
||||||
|
|
||||||
seed_tmp = strtoull(argv[2], &p, 0);
|
|
||||||
if (p == argv[2] || *p != '\0') {
|
|
||||||
fprintf(stderr, "ERROR: Invalid value for SEED1\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
s[2] = (uint32_t)seed_tmp;
|
|
||||||
s[3] = (uint32_t)(seed_tmp >> 32);
|
|
||||||
|
|
||||||
numval = strtoul(argv[3], &p, 0);
|
|
||||||
if (p == argv[3] || *p != '\0') {
|
|
||||||
fprintf(stderr, "ERROR: Invalid value for NVALUE\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (k = 0; k < numval; k++) {
|
|
||||||
printf("0x%08lx\n", (unsigned long) next());
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
--
|
--
|
||||||
-- Pseudo Random Number Generator "xoroshiro128+ 1.0".
|
-- Pseudo Random Number Generator "xoroshiro128+".
|
||||||
--
|
--
|
||||||
-- Author: Joris van Rantwijk <joris@jorisvr.nl>
|
-- Author: Joris van Rantwijk <joris@jorisvr.nl>
|
||||||
--
|
--
|
||||||
|
@ -7,9 +7,9 @@
|
||||||
-- The generator can produce 64 new random bits on every clock cycle.
|
-- The generator can produce 64 new random bits on every clock cycle.
|
||||||
--
|
--
|
||||||
-- The algorithm "xoroshiro128+" is by David Blackman and Sebastiano Vigna.
|
-- The algorithm "xoroshiro128+" is by David Blackman and Sebastiano Vigna.
|
||||||
-- See also http://prng.di.unimi.it/
|
-- See also http://xoroshiro.di.unimi.it/
|
||||||
--
|
--
|
||||||
-- The generator requires a 128-bit seed value, not equal to all zeros.
|
-- The generator requires a 128-bit seed value, not equal to zero.
|
||||||
-- A default seed must be supplied at compile time and will be used
|
-- A default seed must be supplied at compile time and will be used
|
||||||
-- to initialize the generator at reset. The generator also supports
|
-- to initialize the generator at reset. The generator also supports
|
||||||
-- re-seeding at run time.
|
-- re-seeding at run time.
|
||||||
|
@ -19,12 +19,12 @@
|
||||||
--
|
--
|
||||||
-- NOTE: This is not a cryptographic random number generator.
|
-- NOTE: This is not a cryptographic random number generator.
|
||||||
--
|
--
|
||||||
-- NOTE: The least significant output bits are not fully random and
|
-- NOTE: The least significant output bit is less random than
|
||||||
-- fail certain statistical tests.
|
-- all other output bits.
|
||||||
--
|
--
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Copyright (C) 2016-2020 Joris van Rantwijk
|
-- Copyright (C) 2016 Joris van Rantwijk
|
||||||
--
|
--
|
||||||
-- This code is free software; you can redistribute it and/or
|
-- This code is free software; you can redistribute it and/or
|
||||||
-- modify it under the terms of the GNU Lesser General Public
|
-- modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -131,12 +131,12 @@ begin
|
||||||
-- Update internal state.
|
-- Update internal state.
|
||||||
reg_state_s0 <= reg_state_s0 xor
|
reg_state_s0 <= reg_state_s0 xor
|
||||||
reg_state_s1 xor
|
reg_state_s1 xor
|
||||||
rotl(reg_state_s0, 24) xor
|
shiftl(reg_state_s0, 14) xor
|
||||||
shiftl(reg_state_s0, 16) xor
|
shiftl(reg_state_s1, 14) xor
|
||||||
shiftl(reg_state_s1, 16);
|
rotl(reg_state_s0, 55);
|
||||||
|
|
||||||
reg_state_s1 <= rotl(reg_state_s0, 37) xor
|
reg_state_s1 <= rotl(reg_state_s0, 36) xor
|
||||||
rotl(reg_state_s1, 37);
|
rotl(reg_state_s1, 36);
|
||||||
|
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
|
|
|
@ -1,200 +0,0 @@
|
||||||
--
|
|
||||||
-- Pseudo Random Number Generator "xoshiro128++ 1.0".
|
|
||||||
--
|
|
||||||
-- Author: Joris van Rantwijk <joris@jorisvr.nl>
|
|
||||||
--
|
|
||||||
-- This is a 32-bit random number generator in synthesizable VHDL.
|
|
||||||
-- The generator can produce 32 new random bits on every clock cycle.
|
|
||||||
--
|
|
||||||
-- The algorithm "xoshiro128++" is by David Blackman and Sebastiano Vigna.
|
|
||||||
-- See also http://prng.di.unimi.it/
|
|
||||||
--
|
|
||||||
-- The generator requires a 128-bit seed value, not equal to all zeros.
|
|
||||||
-- A default seed must be supplied at compile time and will be used
|
|
||||||
-- to initialize the generator at reset. The generator also supports
|
|
||||||
-- re-seeding at run time.
|
|
||||||
--
|
|
||||||
-- After reset and after re-seeding, one or two clock cycles are needed
|
|
||||||
-- before valid random data appears on the output. The exact delay
|
|
||||||
-- depends on the setting of the "pipeline" parameter.
|
|
||||||
--
|
|
||||||
-- NOTE: This is not a cryptographic random number generator.
|
|
||||||
--
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2020 Joris van Rantwijk
|
|
||||||
--
|
|
||||||
-- This code is free software; you can redistribute it and/or
|
|
||||||
-- modify it under the terms of the GNU Lesser General Public
|
|
||||||
-- License as published by the Free Software Foundation; either
|
|
||||||
-- version 2.1 of the License, or (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- See <https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html>
|
|
||||||
--
|
|
||||||
|
|
||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
use ieee.numeric_std.all;
|
|
||||||
|
|
||||||
|
|
||||||
entity rng_xoshiro128plusplus is
|
|
||||||
|
|
||||||
generic (
|
|
||||||
-- Default seed value.
|
|
||||||
init_seed: std_logic_vector(127 downto 0);
|
|
||||||
|
|
||||||
-- Enable optional pipeline stage in output calculation.
|
|
||||||
-- This uses an extra 32-bit register but tends to improve
|
|
||||||
-- the timing performance of the circuit.
|
|
||||||
-- If the pipeline stage is enabled, two clock cycles are needed
|
|
||||||
-- before valid output appears after reset and after re-seeding.
|
|
||||||
-- If the pipeline stage is disabled, just one clock cycle is needed.
|
|
||||||
pipeline: boolean := true );
|
|
||||||
|
|
||||||
port (
|
|
||||||
|
|
||||||
-- Clock, rising edge active.
|
|
||||||
clk: in std_logic;
|
|
||||||
|
|
||||||
-- Synchronous reset, active high.
|
|
||||||
rst: in std_logic;
|
|
||||||
|
|
||||||
-- High to request re-seeding of the generator.
|
|
||||||
reseed: in std_logic;
|
|
||||||
|
|
||||||
-- New seed value (must be valid when reseed = '1').
|
|
||||||
newseed: in std_logic_vector(127 downto 0);
|
|
||||||
|
|
||||||
-- High when the user accepts the current random data word
|
|
||||||
-- and requests new random data for the next clock cycle.
|
|
||||||
out_ready: in std_logic;
|
|
||||||
|
|
||||||
-- High when valid random data is available on the output.
|
|
||||||
-- This signal is low for 1 or 2 clock cycles after reset and
|
|
||||||
-- after re-seeding, and high in all other cases.
|
|
||||||
out_valid: out std_logic;
|
|
||||||
|
|
||||||
-- Random output data (valid when out_valid = '1').
|
|
||||||
-- A new random word appears after every rising clock edge
|
|
||||||
-- where out_ready = '1'.
|
|
||||||
out_data: out std_logic_vector(31 downto 0) );
|
|
||||||
|
|
||||||
end entity;
|
|
||||||
|
|
||||||
|
|
||||||
architecture xoshiro128plusplus_arch of rng_xoshiro128plusplus is
|
|
||||||
|
|
||||||
-- Internal state of RNG.
|
|
||||||
signal reg_state_s0: std_logic_vector(31 downto 0) := init_seed(31 downto 0);
|
|
||||||
signal reg_state_s1: std_logic_vector(31 downto 0) := init_seed(63 downto 32);
|
|
||||||
signal reg_state_s2: std_logic_vector(31 downto 0) := init_seed(95 downto 64);
|
|
||||||
signal reg_state_s3: std_logic_vector(31 downto 0) := init_seed(127 downto 96);
|
|
||||||
|
|
||||||
-- Optional pipeline register.
|
|
||||||
signal reg_sum_s0s3: std_logic_vector(31 downto 0) := (others => '0');
|
|
||||||
|
|
||||||
-- Output register.
|
|
||||||
signal reg_valid: std_logic := '0';
|
|
||||||
signal reg_nvalid: std_logic := '0';
|
|
||||||
signal reg_output: std_logic_vector(31 downto 0) := (others => '0');
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
-- Drive output signal.
|
|
||||||
out_valid <= reg_valid;
|
|
||||||
out_data <= reg_output;
|
|
||||||
|
|
||||||
-- Synchronous process.
|
|
||||||
process (clk) is
|
|
||||||
variable v_prev_s0: std_logic_vector(31 downto 0) := (others => '0');
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
|
|
||||||
if out_ready = '1' or reg_valid = '0' then
|
|
||||||
|
|
||||||
-- Prepare output word.
|
|
||||||
if pipeline then
|
|
||||||
|
|
||||||
-- Use a pipelined output stage.
|
|
||||||
reg_valid <= reg_nvalid;
|
|
||||||
reg_nvalid <= '1';
|
|
||||||
|
|
||||||
-- Calculate the previous value of s0.
|
|
||||||
v_prev_s0 := reg_state_s0 xor
|
|
||||||
std_logic_vector(
|
|
||||||
rotate_right(unsigned(reg_state_s3),
|
|
||||||
11));
|
|
||||||
|
|
||||||
-- Derive output from prev_s0 and intermediate result
|
|
||||||
-- (prev_s0 + prev_s3) calculated in the previous cycle.
|
|
||||||
reg_output <= std_logic_vector(
|
|
||||||
unsigned(v_prev_s0) +
|
|
||||||
rotate_left(unsigned(reg_sum_s0s3),
|
|
||||||
7));
|
|
||||||
|
|
||||||
-- Update the intermediate register (s0 + s3).
|
|
||||||
reg_sum_s0s3 <= std_logic_vector(
|
|
||||||
unsigned(reg_state_s0) +
|
|
||||||
unsigned(reg_state_s3));
|
|
||||||
|
|
||||||
else
|
|
||||||
|
|
||||||
-- Derive output directly from s0 and s3.
|
|
||||||
-- This requires two cascaded 32-bit adders and
|
|
||||||
-- may limit the timing performance of the circuit.
|
|
||||||
reg_valid <= '1';
|
|
||||||
reg_output <= std_logic_vector(
|
|
||||||
rotate_left(
|
|
||||||
unsigned(reg_state_s0) +
|
|
||||||
unsigned(reg_state_s3), 7) +
|
|
||||||
unsigned(reg_state_s0));
|
|
||||||
|
|
||||||
end if;
|
|
||||||
|
|
||||||
-- Update internal state.
|
|
||||||
reg_state_s0 <= reg_state_s0 xor
|
|
||||||
reg_state_s1 xor
|
|
||||||
reg_state_s3;
|
|
||||||
|
|
||||||
reg_state_s1 <= reg_state_s0 xor
|
|
||||||
reg_state_s1 xor
|
|
||||||
reg_state_s2;
|
|
||||||
|
|
||||||
reg_state_s2 <= reg_state_s0 xor
|
|
||||||
reg_state_s2 xor
|
|
||||||
std_logic_vector(
|
|
||||||
shift_left(unsigned(reg_state_s1), 9));
|
|
||||||
|
|
||||||
reg_state_s3 <= std_logic_vector(
|
|
||||||
rotate_left(
|
|
||||||
unsigned(reg_state_s1 xor
|
|
||||||
reg_state_s3), 11));
|
|
||||||
|
|
||||||
end if;
|
|
||||||
|
|
||||||
-- Re-seed function.
|
|
||||||
if reseed = '1' then
|
|
||||||
reg_state_s0 <= newseed(31 downto 0);
|
|
||||||
reg_state_s1 <= newseed(63 downto 32);
|
|
||||||
reg_state_s2 <= newseed(95 downto 64);
|
|
||||||
reg_state_s3 <= newseed(127 downto 96);
|
|
||||||
reg_valid <= '0';
|
|
||||||
reg_nvalid <= '0';
|
|
||||||
end if;
|
|
||||||
|
|
||||||
-- Synchronous reset.
|
|
||||||
if rst = '1' then
|
|
||||||
reg_state_s0 <= init_seed(31 downto 0);
|
|
||||||
reg_state_s1 <= init_seed(63 downto 32);
|
|
||||||
reg_state_s2 <= init_seed(95 downto 64);
|
|
||||||
reg_state_s3 <= init_seed(127 downto 96);
|
|
||||||
reg_valid <= '0';
|
|
||||||
reg_nvalid <= '0';
|
|
||||||
reg_output <= (others => '0');
|
|
||||||
end if;
|
|
||||||
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
end architecture;
|
|
||||||
|
|
|
@ -6,14 +6,7 @@ GHDL = ghdl
|
||||||
GHDLFLAGS =
|
GHDLFLAGS =
|
||||||
|
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
all: tb_xoshiro128plusplus \
|
all: tb_xoroshiro128plus tb_mt19937 tb_trivium
|
||||||
tb_xoroshiro128plus \
|
|
||||||
tb_mt19937 \
|
|
||||||
tb_trivium
|
|
||||||
|
|
||||||
tb_xoshiro128plusplus: tb_xoshiro128plusplus.o rng_xoshiro128plusplus.o
|
|
||||||
tb_xoshiro128plusplus.o: tb_xoshiro128plusplus.vhdl rng_xoshiro128plusplus.o
|
|
||||||
rng_xoshiro128plusplus.o: ../rtl/rng_xoshiro128plusplus.vhdl
|
|
||||||
|
|
||||||
tb_xoroshiro128plus: tb_xoroshiro128plus.o rng_xoroshiro128plus.o
|
tb_xoroshiro128plus: tb_xoroshiro128plus.o rng_xoroshiro128plus.o
|
||||||
tb_xoroshiro128plus.o: tb_xoroshiro128plus.vhdl rng_xoroshiro128plus.o
|
tb_xoroshiro128plus.o: tb_xoroshiro128plus.vhdl rng_xoroshiro128plus.o
|
||||||
|
|
|
@ -28,8 +28,6 @@ architecture arch of tb_trivium is
|
||||||
|
|
||||||
type test_vectors is array (natural range <>) of test_vector;
|
type test_vectors is array (natural range <>) of test_vector;
|
||||||
|
|
||||||
-- This is a small subset of the test vectors from
|
|
||||||
-- the ECRYPT stream cipher project.
|
|
||||||
constant testvec: test_vectors(0 to 4) := (
|
constant testvec: test_vectors(0 to 4) := (
|
||||||
0 => ( key => x"0053A6F94C9FF24598EB",
|
0 => ( key => x"0053A6F94C9FF24598EB",
|
||||||
iv => x"0D74DB42A91077DE45AC",
|
iv => x"0D74DB42A91077DE45AC",
|
||||||
|
|
|
@ -1,188 +0,0 @@
|
||||||
--
|
|
||||||
-- Test bench for PRNG "xoshiro128++".
|
|
||||||
--
|
|
||||||
|
|
||||||
use std.textio.all;
|
|
||||||
|
|
||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
use ieee.numeric_std.all;
|
|
||||||
|
|
||||||
entity tb_xoshiro128plusplus is
|
|
||||||
end entity;
|
|
||||||
|
|
||||||
architecture arch of tb_xoshiro128plusplus is
|
|
||||||
|
|
||||||
signal clk: std_logic;
|
|
||||||
signal clock_active: boolean := false;
|
|
||||||
|
|
||||||
signal s_rst: std_logic;
|
|
||||||
signal s_reseed: std_logic;
|
|
||||||
signal s_newseed: std_logic_vector(127 downto 0);
|
|
||||||
signal s_ready: std_logic;
|
|
||||||
signal s_valid: std_logic;
|
|
||||||
signal s_data: std_logic_vector(31 downto 0);
|
|
||||||
|
|
||||||
function to_hex_string(s: std_logic_vector)
|
|
||||||
return string
|
|
||||||
is
|
|
||||||
constant alphabet: string(1 to 16) := "0123456789abcdef";
|
|
||||||
variable y: string(1 to s'length/4);
|
|
||||||
begin
|
|
||||||
for i in y'range loop
|
|
||||||
y(i) := alphabet(to_integer(unsigned(s(s'high+4-4*i downto s'high+1-4*i))) + 1);
|
|
||||||
end loop;
|
|
||||||
return y;
|
|
||||||
end function;
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
-- Instantiate PRNG.
|
|
||||||
inst_prng: entity work.rng_xoshiro128plusplus
|
|
||||||
generic map (
|
|
||||||
init_seed => x"0123456789abcdef3141592653589793" )
|
|
||||||
port map (
|
|
||||||
clk => clk,
|
|
||||||
rst => s_rst,
|
|
||||||
reseed => s_reseed,
|
|
||||||
newseed => s_newseed,
|
|
||||||
out_ready => s_ready,
|
|
||||||
out_valid => s_valid,
|
|
||||||
out_data => s_data );
|
|
||||||
|
|
||||||
-- Generate clock.
|
|
||||||
clk <= (not clk) after 10 ns when clock_active else '0';
|
|
||||||
|
|
||||||
-- Main simulation process.
|
|
||||||
process is
|
|
||||||
file outf1: text is out "sim_xoshiro128plusplus_seed1.dat";
|
|
||||||
file outf2: text is out "sim_xoshiro128plusplus_seed2.dat";
|
|
||||||
variable lin: line;
|
|
||||||
variable nskip: integer;
|
|
||||||
variable v: std_logic_vector(31 downto 0);
|
|
||||||
begin
|
|
||||||
|
|
||||||
report "Start test bench";
|
|
||||||
|
|
||||||
-- Reset.
|
|
||||||
s_rst <= '1';
|
|
||||||
s_reseed <= '0';
|
|
||||||
s_newseed <= (others => '0');
|
|
||||||
s_ready <= '0';
|
|
||||||
|
|
||||||
-- Start clock.
|
|
||||||
clock_active <= true;
|
|
||||||
|
|
||||||
-- Wait 2 clock cycles, then end reset.
|
|
||||||
wait for 30 ns;
|
|
||||||
wait until falling_edge(clk);
|
|
||||||
s_rst <= '0';
|
|
||||||
|
|
||||||
-- Wait 1 clock cycle to initialize generator.
|
|
||||||
wait until falling_edge(clk);
|
|
||||||
s_ready <= '1';
|
|
||||||
|
|
||||||
-- Optionally wait an additional pipeline cycle.
|
|
||||||
if s_valid = '0' then
|
|
||||||
report "Detected pipeline delay";
|
|
||||||
wait until falling_edge(clk);
|
|
||||||
end if;
|
|
||||||
|
|
||||||
-- Produce numbers
|
|
||||||
for i in 0 to 999 loop
|
|
||||||
|
|
||||||
-- Check that output is valid.
|
|
||||||
assert s_valid = '1' report "Output not valid";
|
|
||||||
|
|
||||||
-- Write output to file.
|
|
||||||
write(lin, "0x" & to_hex_string(s_data));
|
|
||||||
writeline(outf1, lin);
|
|
||||||
|
|
||||||
-- Sometimes skip cycles.
|
|
||||||
if i mod 5 = 1 then
|
|
||||||
nskip := 1;
|
|
||||||
if i mod 3 = 0 then
|
|
||||||
nskip := nskip + 1;
|
|
||||||
end if;
|
|
||||||
if i mod 11 = 0 then
|
|
||||||
nskip := nskip + 1;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
v := s_data;
|
|
||||||
s_ready <= '0';
|
|
||||||
for t in 1 to nskip loop
|
|
||||||
wait until falling_edge(clk);
|
|
||||||
assert s_valid = '1' report "Output not valid";
|
|
||||||
assert s_data = v report "Output changed while not ready";
|
|
||||||
end loop;
|
|
||||||
s_ready <= '1';
|
|
||||||
end if;
|
|
||||||
|
|
||||||
-- Go to next cycle.
|
|
||||||
wait until falling_edge(clk);
|
|
||||||
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
-- Re-seed generator.
|
|
||||||
report "Re-seed generator";
|
|
||||||
s_reseed <= '1';
|
|
||||||
s_newseed <= x"3141592653589793fedcba9876543210";
|
|
||||||
s_ready <= '0';
|
|
||||||
wait until falling_edge(clk);
|
|
||||||
s_reseed <= '0';
|
|
||||||
s_newseed <= (others => '0');
|
|
||||||
|
|
||||||
-- Wait 1 clock cycle to re-seed generator.
|
|
||||||
wait until falling_edge(clk);
|
|
||||||
s_ready <= '1';
|
|
||||||
|
|
||||||
-- Optionally wait an additional pipeline cycle.
|
|
||||||
if s_valid = '0' then
|
|
||||||
report "Detected pipeline delay";
|
|
||||||
wait until falling_edge(clk);
|
|
||||||
end if;
|
|
||||||
|
|
||||||
-- Produce numbers
|
|
||||||
for i in 0 to 999 loop
|
|
||||||
|
|
||||||
-- Check that output is valid.
|
|
||||||
assert s_valid = '1' report "Output not valid";
|
|
||||||
|
|
||||||
-- Write output to file.
|
|
||||||
write(lin, "0x" & to_hex_string(s_data));
|
|
||||||
writeline(outf2, lin);
|
|
||||||
|
|
||||||
-- Sometimes skip cycles.
|
|
||||||
if i mod 5 = 2 then
|
|
||||||
nskip := 1;
|
|
||||||
if i mod 3 = 0 then
|
|
||||||
nskip := nskip + 1;
|
|
||||||
end if;
|
|
||||||
if i mod 11 = 0 then
|
|
||||||
nskip := nskip + 1;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
v := s_data;
|
|
||||||
s_ready <= '0';
|
|
||||||
for t in 1 to nskip loop
|
|
||||||
wait until falling_edge(clk);
|
|
||||||
assert s_valid = '1' report "Output not valid";
|
|
||||||
assert s_data = v report "Output changed while not ready";
|
|
||||||
end loop;
|
|
||||||
s_ready <= '1';
|
|
||||||
end if;
|
|
||||||
|
|
||||||
-- Go to next cycle.
|
|
||||||
wait until falling_edge(clk);
|
|
||||||
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
-- End simulation.
|
|
||||||
report "End testbench";
|
|
||||||
|
|
||||||
clock_active <= false;
|
|
||||||
wait;
|
|
||||||
|
|
||||||
end process;
|
|
||||||
|
|
||||||
end architecture;
|
|
|
@ -1,33 +0,0 @@
|
||||||
|
|
||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
|
|
||||||
entity toptriv is
|
|
||||||
port (
|
|
||||||
clk : in std_logic;
|
|
||||||
rst : in std_logic;
|
|
||||||
ready: in std_logic;
|
|
||||||
valid: out std_logic;
|
|
||||||
data: out std_logic_vector(31 downto 0) );
|
|
||||||
end toptriv;
|
|
||||||
|
|
||||||
architecture arch of toptriv is
|
|
||||||
begin
|
|
||||||
|
|
||||||
inst_prng: entity work.rng_trivium
|
|
||||||
generic map (
|
|
||||||
num_bits => 32,
|
|
||||||
init_key => x"31415926535897932384",
|
|
||||||
init_iv => x"0123456789abcdefa50f" )
|
|
||||||
port map (
|
|
||||||
clk => clk,
|
|
||||||
rst => rst,
|
|
||||||
reseed => '0',
|
|
||||||
newkey => (others => '0'),
|
|
||||||
newiv => (others => '0'),
|
|
||||||
out_ready => ready,
|
|
||||||
out_valid => valid,
|
|
||||||
out_data => data );
|
|
||||||
|
|
||||||
end arch;
|
|
||||||
|
|
|
@ -2,16 +2,16 @@
|
||||||
library ieee;
|
library ieee;
|
||||||
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
||||||
|
|
||||||
entity top_xoroshiro128plus is
|
entity topxs is
|
||||||
port (
|
port (
|
||||||
clk : in std_logic;
|
clk : in std_logic;
|
||||||
rst : in std_logic;
|
rst : in std_logic;
|
||||||
ready: in std_logic;
|
ready: in std_logic;
|
||||||
valid: out std_logic;
|
valid: out std_logic;
|
||||||
data: out std_logic_vector(63 downto 0) );
|
data: out std_logic_vector(63 downto 0) );
|
||||||
end top_xoroshiro128plus;
|
end topxs;
|
||||||
|
|
||||||
architecture arch of top_xoroshiro128plus is
|
architecture arch of topxs is
|
||||||
begin
|
begin
|
||||||
|
|
||||||
inst_prng: entity work.rng_xoroshiro128plus
|
inst_prng: entity work.rng_xoroshiro128plus
|
|
@ -1,30 +0,0 @@
|
||||||
|
|
||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
|
|
||||||
entity top_xoshiro128plusplus is
|
|
||||||
port (
|
|
||||||
clk : in std_logic;
|
|
||||||
rst : in std_logic;
|
|
||||||
ready: in std_logic;
|
|
||||||
valid: out std_logic;
|
|
||||||
data: out std_logic_vector(31 downto 0) );
|
|
||||||
end top_xoshiro128plusplus;
|
|
||||||
|
|
||||||
architecture arch of top_xoshiro128plusplus is
|
|
||||||
begin
|
|
||||||
|
|
||||||
inst_prng: entity work.rng_xoshiro128plusplus
|
|
||||||
generic map (
|
|
||||||
init_seed => x"0123456789abcdef3141592653589793" )
|
|
||||||
port map (
|
|
||||||
clk => clk,
|
|
||||||
rst => rst,
|
|
||||||
reseed => '0',
|
|
||||||
newseed => (others => '0'),
|
|
||||||
out_ready => ready,
|
|
||||||
out_valid => valid,
|
|
||||||
out_data => data );
|
|
||||||
|
|
||||||
end arch;
|
|
||||||
|
|
Loading…
Reference in New Issue