Pseudo Random Number Generator

Vinayaka's Note:

  • Check if there are any better solution for this.

  • For n-bits, this approach can generate a max of (2^n -1) patterns

RTL for PRNG

module prng_v1 #(

parameter int unsigned IDX [16] = {0,1,0,1,0,1,0,1,0,0,0,0,0,0,0,0},

parameter int unsigned WIDTH = 16

)(

output logic [WIDTH-1:0] prng_o,

input logic clk,

input logic rstn

);

/////////////////////////////////////////////////////

// Declaration

/////////////////////////////////////////////////////

logic [WIDTH-1:0] buffer;

/////////////////////////////////////////////////////

// Logic

/////////////////////////////////////////////////////

always_ff@(posedge clk, negedge rstn) begin

if (~rstn) begin

buffer <= '0;

end

else begin

for (int i=0; i<WIDTH; i++) begin

if (i == WIDTH-1) buffer[i] <= ~buffer[0];

else if (IDX[i] == 1) buffer[i] <= buffer[i+1] ^ buffer[WIDTH-1];

else buffer[i] <= buffer[i+1];

end

end

end

assign prng_o = buffer;

endmodule

module prng_v2 #(

parameter int unsigned WIDTH = 16

)(

output logic [WIDTH-1:0] prng_o,

input logic clk,

input logic rstn

);

/////////////////////////////////////////////////////

// Declaration

/////////////////////////////////////////////////////

logic [WIDTH-1:0] buffer;

/////////////////////////////////////////////////////

// Logic

/////////////////////////////////////////////////////

always_ff@(posedge clk, negedge rstn) begin

if (~rstn) begin

buffer <= '1;

end

else begin

for (int i=0; i<WIDTH; i++) begin

if (i == WIDTH-1) buffer[i] <= buffer[0];

else if (i== 0) buffer[i] <= buffer[10]^buffer[12]^buffer[13]^buffer[15];

else buffer[i] <= buffer[i+1];

end

end

end

assign prng_o = buffer;

endmodule

TB

module tb;

parameter int unsigned WIDTH = 16;

logic [WIDTH-1:0] prng_v1;

logic [WIDTH-1:0] prng_v2;

logic clk;

logic rstn;

prng_v1 #(.WIDTH(WIDTH)) u_inst1 (.prng_o(prng_v1), .clk(clk), .rstn(rstn));

prng_v2 #(.WIDTH(WIDTH)) u_inst2 (.prng_o(prng_v2), .clk(clk), .rstn(rstn));


initial begin

clk = '0;

rstn = '0;

fork

begin

#100;

rstn = '1;

end

begin

forever begin

clk = #5 ~clk;

end

end

begin

#500;

$finish;

end

join

end

initial begin

$dumpfile("dump.vcd");

$dumpvars;

end

endmodule

Simulation output