/* * rng.v * * Very simple 32-bits PRNG using a few underlying LFSR. * * Copyright (C) 2014 Ettus Corporation LLC * Copyright 2018 Ettus Research, a National Instruments Company * * SPDX-License-Identifier: LGPL-3.0-or-later * * vim: ts=4 sw=4 */ `ifdef SIM `default_nettype none `endif // --------------------------------------------------------------------------- // Main RNG // --------------------------------------------------------------------------- module rng( output reg [31:0] out, input wire clk, input wire rst ); // Signals wire [4:0] out5, out5rev; wire [7:0] out8; wire [11:0] out12; wire [15:0] out16; // Instanciate 4 LFSRs of different lengths lfsr #(.WIDTH( 5), .POLY( 5'b01001)) lfsr5 (.out(out5), .clk(clk), .rst(rst)); lfsr #(.WIDTH( 8), .POLY( 8'h71 )) lfsr8 (.out(out8), .clk(clk), .rst(rst)); lfsr #(.WIDTH(12), .POLY(12'hc11 )) lfsr12 (.out(out12), .clk(clk), .rst(rst)); lfsr #(.WIDTH(16), .POLY(16'h6701 )) lfsr16 (.out(out16), .clk(clk), .rst(rst)); // Reverse the 5 bit LFSR output genvar i; generate for (i=0; i<5; i=i+1) assign out5rev[i] = out5[4-i]; endgenerate // Combine the outputs 'somehow' always @(posedge clk) out <= { out16[15:11] ^ out5rev, // 5 bits out16[10:2], // 9 bits out16[1:0] ^ out12[11:10], // 2 bits out12[9:2], // 8 bits out12[1:0] ^ out8[7:6], // 2 bits out8[5:0] // 6 bits }; endmodule // rng // --------------------------------------------------------------------------- // LFSR sub module // --------------------------------------------------------------------------- module lfsr #( parameter integer WIDTH = 8, parameter POLY = 8'h71 )( output reg [WIDTH-1:0] out, input wire clk, input wire rst ); // Signals wire fb; // Linear Feedback assign fb = ^(out & POLY); // Register always @(posedge clk) if (rst) out <= { {(WIDTH-1){1'b0}}, 1'b1 }; else out <= { fb, out[WIDTH-1:1] }; endmodule // lfsr