Looking for good 32 bit pseudo RNG in SystemVerilog. - Page 1
Forum section: electronics / general

author: BrianHG
author_rank: Super Contributor
timestamp: June 26, 2021, 07:22:15 pm
content: Well, open cores failed as their verilog 32bit pseudo random number gen is garbagely written and only makes a half repeating pattern with 0s coming up in regular patterns as seen using is to generate video white noise on a 2048x1080. So much for their claim of being really random.I need a good 150 million random 32 bit numbers a second.Google has failed me to find something clean unless I will need to test everything I find.Does anyone have anything good laying around.

author: SMB784
author_rank: Frequent Contributor
timestamp: June 26, 2021, 07:35:52 pm
content: Why not a 32 bit LFSR pseudorandom number generator? This will provide 232=4.3 billion random numbers, with a cycling time of that many clocks. At 4 GHz it would take more than 1 second to run through all of the valuese.g.Code:module LFSR_rng#()(input logic clk,output logic [31:0] rand_out);logic [31:0] rand_ff=$urandom();always_ff @(posedge clk)beginrand_ff<={(rand_ff^rand_ff^rand_ff^rand_ff),rand_ff[31:1]};rand_out<=rand_ffendendmodule*** EDIT *** made clocked module

author: BrianHG
author_rank: Super Contributor
timestamp: June 26, 2021, 07:44:38 pm
content: Testing... damn 10minute compile time for the project.I have a dead LFSR 42bit one with bad xor coefficients and a 32 bit one like yours, but with different coefficients.Let's see what yours produces.

author: BrianHG
author_rank: Super Contributor
timestamp: June 26, 2021, 07:53:38 pm
content: Quote from: SMB784 on June 26, 2021, 07:35:52 pmNot possible with this formula. It will repeat very rapidly. Especially if the result is ever 0, it will always return 0 from that point on. A good 32 bit random number generator needs to have at least 64 bits or 128 bits at it's core.

author: BrianHG
author_rank: Super Contributor
timestamp: June 26, 2021, 08:02:17 pm
content: Your RND produces a greenish snow, meaning since I'm using the 32 bit output as 8bit A,R,G,B, bits 15 to 8, most likely 15 and 14 prefer to be high most of the time. Random snow should average grey.

author: SiliconWizard
author_rank: Super Contributor
timestamp: June 26, 2021, 08:06:56 pm
content: I haven't had to implement this in HDL so far. But I have in software on several occasions, and I have always used the same ever since I read about it and tested it: taken from the Art of Computer Programming (Knuth). Various statistical tests show this one has very good "randomness", despite its being extremely simple.It only requires one adder (width same as the generated numbers.)But it does require a memory of the 55 last generated numbers. It's not a lot, but see if it's OK in your case.Those 55 values need to be initialized, so whereas a basic RNG requires only 1 seed number, this one requires 55. If you don't care about the sequence being always the same from reset, you can of course fill it with 55 pre-generated random values.Should be pretty simple to implement in HDL.The algorithm is described in Volume 2 (Seminumerical algorithms), "3.2.2. Other methods", Algorithm A (Additive number generator). If you don't have the book handy, I can post the algorithm. It's very simple.

author: daqq
author_rank: Super Contributor
timestamp: June 26, 2021, 08:10:01 pm
content: How many resources do you have available? Look for common hash functions (MD5, SHA256...), take one or more round out of them and just feed them back into itself - loop the pipe. Then try tapping into the output. Ignore the 96 or more extra bits, just feed them into the loop. It'll be some time till that loops. Total overkill, but will work.

author: BrianHG
author_rank: Super Contributor
timestamp: June 26, 2021, 08:24:14 pm
content: This guy hasn't a clue how verilog or FPGAs work, he has a good formula, but, screwed up the implementation. He didn't do proper testing of the individual components, otherwise he would have seen his LFSR section generates nothing but a tiny repetitive string of 1s and 0s every few hundred iterations in the same spot of bits.https://opencores.org/projects/systemc_rngThis is his code: rng.vCode:////////////////////////////////////////////////////////////////////////// //////// Random Number Generator //////// //////// This file is part of the SystemC RNG //////// //////// Description: //////// //////// Implementation of random number generator //////// //////// To Do: //////// - done //////// //////// Author(s): //////// - Javier Castillo, javier.castillo@urjc.es //////// //////// This core is provided by Universidad Rey Juan Carlos //////// http://www.escet.urjc.es/~jmartine //////// ////////////////////////////////////////////////////////////////////////////// //////// Copyright (C) 2000 Authors and OPENCORES.ORG //////// //////// This source file may be used and distributed without //////// restriction provided that this copyright statement is not //////// removed from the file and that any derivative work contains //////// the original copyright notice and the associated disclaimer. //////// //////// This source file 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. //////// //////// This source is distributed in the hope that it will be //////// useful, but WITHOUT ANY WARRANTY; without even the implied //////// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //////// PURPOSE. See the GNU Lesser General Public License for more //////// details. //////// //////// You should have received a copy of the GNU Lesser General //////// Public License along with this source; if not, download it //////// from http://www.opencores.org/lgpl.shtml //////// ////////////////////////////////////////////////////////////////////////////// CVS Revision History//// $Log: not supported by cvs2svn $// Revision 1.3 2005/07/30 20:07:26 jcastillo// Correct bit 28. Correct assignation to bit 31//// Revision 1.2 2005/07/29 09:13:06 jcastillo// Correct bit 28 of CASR//// Revision 1.1 2004/09/23 09:43:06 jcastillo// Verilog first import//`timescale 10ns/1nsmodule rng(clk,reset,loadseed_i,seed_i,number_o);input clk;input reset;input loadseed_i;input [31:0] seed_i;output [31:0] number_o;reg [31:0] number_o;reg [42:0] LFSR_reg;reg [36:0] CASR_reg;//CASR:reg[36:0] CASR_varCASR,CASR_outCASR;always @(posedge clk or negedge reset)beginif (!reset )beginCASR_reg = (1);endelsebeginif (loadseed_i )beginCASR_varCASR [36:32]=0;CASR_varCASR [31:0]=seed_i ;CASR_reg = (CASR_varCASR );endelsebeginCASR_varCASR =CASR_reg ;CASR_outCASR =CASR_varCASR ^CASR_varCASR ;CASR_outCASR =CASR_varCASR ^CASR_varCASR ;CASR_outCASR =CASR_varCASR ^CASR_varCASR ;CASR_outCASR =CASR_varCASR ^CASR_varCASR ;CASR_outCASR =CASR_varCASR ^CASR_varCASR ;CASR_outCASR =CASR_varCASR ^CASR_varCASR ;CASR_outCASR =CASR_varCASR ^CASR_varCASR ;CASR_outCASR =CASR_varCASR ^CASR_varCASR ;CASR_outCASR =CASR_varCASR ^CASR_varCASR ;CASR_outCASR =CASR_varCASR ^CASR_varCASR ^CASR_varCASR ;CASR_outCASR =CASR_varCASR ^CASR_varCASR ;CASR_outCASR =CASR_varCASR ^CASR_varCASR ;CASR_outCASR =CASR_varCASR ^CASR_varCASR ;CASR_outCASR =CASR_varCASR ^CASR_varCASR ;CASR_outCASR =CASR_varCASR ^CASR_varCASR ;CASR_outCASR =CASR_varCASR ^CASR_varCASR ;CASR_outCASR =CASR_varCASR ^CASR_varCASR ;CASR_outCASR =CASR_varCASR ^CASR_varCASR ;CASR_outCASR =CASR_varCASR ^CASR_varCASR ;CASR_outCASR =CASR_varCASR ^CASR_varCASR ;CASR_outCASR =CASR_varCASR ^CASR_varCASR ;CASR_outCASR =CASR_varCASR ^CASR_varCASR ;CASR_outCASR =CASR_varCASR ^CASR_varCASR ;CASR_outCASR =CASR_varCASR ^CASR_varCASR ;CASR_outCASR =CASR_varCASR ^CASR_varCASR ;CASR_outCASR =CASR_varCASR ^CASR_varCASR ;CASR_outCASR =CASR_varCASR ^CASR_varCASR ;CASR_outCASR =CASR_varCASR ^CASR_varCASR ;CASR_outCASR =CASR_varCASR ^CASR_varCASR ;CASR_outCASR =CASR_varCASR ^CASR_varCASR ;CASR_outCASR =CASR_varCASR ^CASR_varCASR ;CASR_outCASR =CASR_varCASR ^CASR_varCASR ;CASR_outCASR =CASR_varCASR ^CASR_varCASR ;CASR_outCASR =CASR_varCASR ^CASR_varCASR ;CASR_outCASR =CASR_varCASR ^CASR_varCASR ;CASR_outCASR =CASR_varCASR ^CASR_varCASR ;CASR_outCASR =CASR_varCASR ^CASR_varCASR ;CASR_reg = (CASR_outCASR );endendend//LFSR:reg[42:0] LFSR_varLFSR;reg outbitLFSR;always @(posedge clk or negedge reset)beginif (!reset )beginLFSR_reg = (1);endelsebeginif (loadseed_i )beginLFSR_varLFSR [42:32]=0;LFSR_varLFSR [31:0]=seed_i ;LFSR_reg = (LFSR_varLFSR );endelsebeginLFSR_varLFSR =LFSR_reg ;outbitLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ^outbitLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ^outbitLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_varLFSR =LFSR_varLFSR ^outbitLFSR ;LFSR_varLFSR =LFSR_varLFSR ;LFSR_reg = (LFSR_varLFSR );endendend//combinate:always @(posedge clk or negedge reset)beginif (!reset )beginnumber_o = (0);endelsebeginnumber_o = (LFSR_reg [31:0]^CASR_reg[31:0]);endendendmoduleI've changed his 'LFSR' portion to this:Code:if (ena) beginLFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ^LFSR_varLFSR  ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ^LFSR_varLFSR  ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR  <=LFSR_varLFSR ;LFSR_varLFSR  <=LFSR_varLFSR ;LFSR_varLFSR  <=LFSR_varLFSR ;LFSR_varLFSR  <=LFSR_varLFSR ;LFSR_varLFSR  <=LFSR_varLFSR ;LFSR_varLFSR  <=LFSR_varLFSR ;LFSR_varLFSR  <=LFSR_varLFSR ;LFSR_varLFSR  <=LFSR_varLFSR ;LFSR_varLFSR  <=LFSR_varLFSR ^LFSR_varLFSR  ;LFSR_varLFSR  <=LFSR_varLFSR ;endAt least now it generates a close to average grey semi fine snow instead of a scrolling blue weird tree pattern. It's like he is confusing part C code with verilog parallel registers and he didn't bother to verify his results were truly non-pattern generating over millions of itterations.I'm now debugging his CASR random number generator part.It already looks far more random and balanced compared to SMB784's greenish chunky with circular waves scrolling through:Code:rand_ff<={(rand_ff^rand_ff^rand_ff^rand_ff),rand_ff[31:1]};

author: BrianHG
author_rank: Super Contributor
timestamp: June 26, 2021, 08:32:14 pm
content: Wow, after patching his CASR section, it truly creates a fine snow.Now to merge the 2 with the final XOR.

author: BrianHG
author_rank: Super Contributor
timestamp: June 26, 2021, 09:01:13 pm
content: Ok, I can officially call this snow:Code:module white_noise ( clk, rst, ena, out );input clk, rst, ena;output [31:0] out ;wire [31:0] out = number_o[31:0] ;reg [31:0] number_o;reg [42:0] LFSR_reg;reg [36:0] CASR_reg;//CASR:reg[36:0] CASR_varCASR;always @(posedge clk ) beginif ( rst ) CASR_varCASR <= (37'h21616D3EA9);else beginif (ena) beginCASR_varCASR <=CASR_varCASR ^CASR_varCASR ;CASR_varCASR <=CASR_varCASR ^CASR_varCASR ;CASR_varCASR <=CASR_varCASR ^CASR_varCASR ;CASR_varCASR <=CASR_varCASR ^CASR_varCASR ;CASR_varCASR <=CASR_varCASR ^CASR_varCASR ;CASR_varCASR <=CASR_varCASR ^CASR_varCASR ;CASR_varCASR <=CASR_varCASR ^CASR_varCASR ;CASR_varCASR <=CASR_varCASR ^CASR_varCASR ;CASR_varCASR <=CASR_varCASR ^CASR_varCASR ;CASR_varCASR <=CASR_varCASR ^CASR_varCASR ^CASR_varCASR ;CASR_varCASR <=CASR_varCASR ^CASR_varCASR ;CASR_varCASR <=CASR_varCASR ^CASR_varCASR ;CASR_varCASR <=CASR_varCASR ^CASR_varCASR ;CASR_varCASR <=CASR_varCASR ^CASR_varCASR ;CASR_varCASR <=CASR_varCASR ^CASR_varCASR ;CASR_varCASR <=CASR_varCASR ^CASR_varCASR ;CASR_varCASR <=CASR_varCASR ^CASR_varCASR ;CASR_varCASR <=CASR_varCASR ^CASR_varCASR ;CASR_varCASR <=CASR_varCASR ^CASR_varCASR ;CASR_varCASR <=CASR_varCASR ^CASR_varCASR ;CASR_varCASR <=CASR_varCASR ^CASR_varCASR ;CASR_varCASR <=CASR_varCASR ^CASR_varCASR ;CASR_varCASR <=CASR_varCASR ^CASR_varCASR ;CASR_varCASR <=CASR_varCASR ^CASR_varCASR ;CASR_varCASR <=CASR_varCASR ^CASR_varCASR ;CASR_varCASR <=CASR_varCASR ^CASR_varCASR ;CASR_varCASR <=CASR_varCASR  ^CASR_varCASR ;CASR_varCASR  <=CASR_varCASR  ^CASR_varCASR ;CASR_varCASR  <=CASR_varCASR  ^CASR_varCASR ;CASR_varCASR  <=CASR_varCASR  ^CASR_varCASR ;CASR_varCASR  <=CASR_varCASR  ^CASR_varCASR ;CASR_varCASR  <=CASR_varCASR  ^CASR_varCASR ;CASR_varCASR  <=CASR_varCASR  ^CASR_varCASR ;CASR_varCASR  <=CASR_varCASR  ^CASR_varCASR ;CASR_varCASR  <=CASR_varCASR  ^CASR_varCASR ;CASR_varCASR  <=CASR_varCASR  ^CASR_varCASR ;CASR_varCASR  <=CASR_varCASR ^CASR_varCASR ;endendend//LFSR:reg[42:0] LFSR_varLFSR;always @(posedge clk) beginif ( rst ) LFSR_varLFSR <= (43'h2264311BAA6);else beginif (ena) beginLFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ^LFSR_varLFSR  ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ^LFSR_varLFSR  ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR <=LFSR_varLFSR ;LFSR_varLFSR  <=LFSR_varLFSR ;LFSR_varLFSR  <=LFSR_varLFSR ;LFSR_varLFSR  <=LFSR_varLFSR ;LFSR_varLFSR  <=LFSR_varLFSR ;LFSR_varLFSR  <=LFSR_varLFSR ;LFSR_varLFSR  <=LFSR_varLFSR ;LFSR_varLFSR  <=LFSR_varLFSR ;LFSR_varLFSR  <=LFSR_varLFSR ;LFSR_varLFSR  <=LFSR_varLFSR ^LFSR_varLFSR  ;LFSR_varLFSR  <=LFSR_varLFSR ;endendend//combinate:always @(posedge clk) beginif ( rst ) number_o <= (0);else if (ena) number_o <= (LFSR_varLFSR [31:0]^CASR_varCASR[31:0]);endendmoduleIt's basically a corrected interpretation of the code given on open-cores:https://opencores.org/projects/systemc_rng(I do realize I could have simplified the to generators down to a single line...)

author: SMB784
author_rank: Frequent Contributor
timestamp: June 26, 2021, 09:43:24 pm
content: Quote from: BrianHG on June 26, 2021, 07:53:38 pmThis sequence of taps should correspond to a maximum length LFSR sequence, i.e. 232-1 numbers, assuming the seed number isn't 0. See just above example C in this Wikipedia article:https://en.wikipedia.org/wiki/Linear-feedback_shift_register#%3A%7E%3Atext%3DA_maximum-length_LFSR_produces%2Ccase_it_will_never_change.?wprov=sfla1Perhaps I have implemented the taps wrong though.

author: BrianHG
author_rank: Super Contributor
timestamp: June 26, 2021, 10:19:21 pm
content: Quote from: SMB784 on June 26, 2021, 09:43:24 pmNot even close. 0 is a possible random number, and it the generator cannot produce it, it's not random.If 0 is hit, your generator will get stuck.Your generator clearly made fat blobbish green like pixels though it was kinda grainy.the video had an angular pattern scrolling through it showing a pattern and degree of repeatability.Tanking the bottom 32 bits of the above posted 43 bit LFSR, once I corrected the coding, generated an average gray white noise with twice as fine pixels as yours. Though there was a hint of repeatability. The bottom 32 bits of the 37 bit CASR generator made a really fine, super sharp average white snow, but you could tell there was a faint background pattern scrolling to the left through the video. The combo XOR of the LFSR and CASR really made a random snow with no discernible pattern in the video.

author: BrianHG
author_rank: Super Contributor
timestamp: June 26, 2021, 10:26:06 pm
content: I'm happy with the combo 43 LFSR & 37 bit CASR generator. I'll have my DDR3 ram controller up in a day or two using the generator to drive a 1080p 32 bit color HDMI out demo with 2D drawing effects on Arrow's Deca board.

author: RoGeorge
author_rank: Super Contributor
timestamp: June 26, 2021, 11:55:16 pm
content: How about a true random generator:QuoteSource:http://forums.xilinx.com/xlnx/attachments/xlnx/EDK/27322/1/HighSpeedTrueRandomNumberGeneratorsinXilinxFPGAs.pdf

author: SMB784
author_rank: Frequent Contributor
timestamp: June 27, 2021, 12:45:28 am
content: Quote from: BrianHG on June 26, 2021, 10:19:21 pmI don't know the exact implementation you are using the 32bit LFSR for, and I'm also not familiar with the green blobs that you mention, but I'm glad that you have discovered a solution that will work.The LFSR not generating 0 is just a fact of LFSRs. (https://en.wikipedia.org/wiki/Maximum_length_sequence?wprov=sfla1). A 43bit LFSR is no different in this regard. This is why it is a pseudorandom number generator - it doesn't generate truly random numbers, which would naturally include 0. However, for large LFSRs, this basically doesn't matter, given that 0 is just one number in a field of billions to trillions for large LFSRsOn a different note, what seed number are you using? I have found that $urandom() doesn't always work correctly, so you may have to give it an explicitl random seed.

author: hamster_nz
author_rank: Super Contributor
timestamp: June 27, 2021, 02:15:05 am
content: Obvious:Just invert the output to get pseudo random numbers between 0 and 2^n-2.Maybe less obvious:The raw output of a LFSR-based PRNG can't be even close to random - each output value is only generated once during the entire cycle. So for a maximal 16-bit LFSR if you have generated the number "1235" you can be sure that any of the next 65534 iterations you will not see 1235 . The more numbers you generate, the more you know about the pool of numbers that is left to be generated, and when the numbers will next appear.Even less obvious answer:Take the DFT of the output of a maximal LFSR bitstream (where a '0' is taken as y=-1 and a '1' is taken as y=1) and see if that looks at all random.This is also why the DC / 0Hz value of 0.5*(2^n-1) (or -0.5*(2^n-1)) is 'correct' if using the LFSR as a noise source.

author: BrianHG
author_rank: Super Contributor
timestamp: June 27, 2021, 02:31:31 am
content: Quote from: SMB784 on June 27, 2021, 12:45:28 amI never asked for true randomness, just that the result should be random like.The 43bit LFSR allows 0 as a result on the 32 bit LSBs since the upper hidden bits do not need to be at the same time, so 0 on bits 31:0 wont kill the generator.Rotating 32 bits with 4 xor points isn't enough and seems to favor strings of '011's or '110's between bits 10 & 29 as the color of my snow was tinted green.Your LFSR just wasn't wide enough and alone, even the 42bit one I has also has a characteristic to the snow, though it's average color was gray. Xor-ing it with the CASR make the result truly like an old analog TV tuned to an empty station, except the snow was colored.Again, using the CASR alone would look like as if an analog HDTV would have been tuned into some high frequency snow, but just artificially overkill on it's own.If you arent going to plot these generators continuously on 8mgabyte graphic display, just picking 2 adjacent numbers from the generator will look random.Also, for your 32bit number generator, whatever number goes in, the next one is always guaranteed to be the same. So, at 4GHz, in theory I should see every 32 bit number, right?This wont happen as the LFSR generators do not achieve 100% coverage. Also randomness means with only 1 pass, there should be a good percentage of repeats. The extra bits with a 42bit LFSR allow for some of these circumstances when operating with only the first 32 bits, though it is still not enough.

author: BrianHG
author_rank: Super Contributor
timestamp: June 27, 2021, 02:32:30 am
content: Quote from: hamster_nz on June 27, 2021, 02:15:05 amThanks.

author: emece67
author_rank: Frequent Contributor
timestamp: June 27, 2021, 07:43:11 am
content: .

author: filssavi
author_rank: Frequent Contributor
timestamp: June 27, 2021, 07:57:39 am
content: Quote from: emece67 on June 27, 2021, 07:43:11 amJust out of curiosity what type or TRNG implementation have you used?I assume you used free running oscillators as a source of entropy, maybe seeding something like a mersenne twister for throughput…Are my guess correct (if you can speak about it of course)

author: Canis Dirus Leidy
author_rank: Regular Contributor
timestamp: June 27, 2021, 08:18:47 am
content: Speaking about LFSR and randomness. There aremethods using multiple LFSRs(1), such as "stop-and-go generator", Hollmann's cascade or just several parallel LFSRs, like inthisGaussian noise generator.1. In Russian, but I think that the skeleton diagrams are obvious.

author: FenTiger
author_rank: Regular Contributor
timestamp: June 27, 2021, 09:40:36 am
content: I'm coming in late to this thread, perhaps, but I've had some success with this one:https://www.alexforencich.com/wiki/en/\verilog/mersenne/readmeI did have to make a couple of fixes to it; I'll dig them out if anyone's interested.(Edit: fixed the link; thanks rstofer!)

author: emece67
author_rank: Frequent Contributor
timestamp: June 27, 2021, 10:46:11 am
content: .

author: rstofer
author_rank: Super Contributor
timestamp: June 27, 2021, 03:31:00 pm
content: Quote from: FenTiger on June 27, 2021, 09:40:36 amThat link is missing a 'v' in \veriloghttps://www.alexforencich.com/wiki/en/\verilog/mersenne/readme

author: BrianHG
author_rank: Super Contributor
timestamp: June 27, 2021, 04:41:06 pm
content: For whoever is interested, I've cleaned up the random code, here it is:The pipeline for the random numbers is 2 unless you make the 'out <= ... ' into an always_comb.Code:module rnd ( clk, rst, ena, load, seed, out );input clk, rst, ena, load;input [31:0] seed ;output reg [31:0] out ;reg[36:0] CASR;reg[42:0] LFSR;always @(posedge clk ) beginif ( rst ) beginCASR <= (37'h1); // Random starting point.LFSR <= (43'h1); // Random starting point.end else if (load) beginCASR <= 37'(seed) | 33'h100000000 ; // Load seed, protect from a seed of 0.LFSR <= 43'(seed) | 33'h100000000 ; // Load seed, protect from a seed of 0.end else if (ena) beginCASR[36:0] <= ( {CASR[35:0],CASR} ^ {CASR,CASR[36:1]} ^ CASR<<27 ) ;LFSR[42:0] <= ( {LFSR[41:0],LFSR} ^ LFSR<<41 ^ LFSR<<20 ^ LFSR<<1 ) ;out [31:0] <= ( LFSR [31:0] ^ CASR[31:0] );endendendmodule