Verilog: [2] Pseudo-random number generator (c_rand.v)

Broken thoughts:

Due to the busyness of the brothers, the early algorithm has not had time to test, so the FOC project is temporarily suspended for a while~

At the same time, the code of the early part of Basic Verilog is relatively simple, so I am also trying to update it a day! People can't be idle, wow, doesn't it mean that life is constantly struggling (manual ditch head)

Table of contents

1 module function

2 module code

3 Module Ideas

4 TestBench and simulation results


1 module function

Triggered by the rising edge of the clock or the falling edge of the reset signal, the generation of pseudo-random numbers is realized by multiplication and addition operations.

2 module code

// C runtime library random number generator
//
// uses 32 logic cells for DFF/ADD and 8 DSP blocks for the
// 32x18=>32 multiply

module c_rand (clk,rst,reseed,seed_val,out);
input clk,rst,reseed;
input [31:0] seed_val;
output [15:0] out;
wire [15:0] out;

reg [31:0] state;

always @(posedge clk or posedge rst) begin
	if (rst) state <= 0;
	else begin
		if (reseed) state <= seed_val;
		else begin
			state <= state * 32'h343fd + 32'h269EC3;
		end
	end
end

assign out = (state >> 16) & 16'h7fff;

endmodule

3 Module Ideas

The idea here is relatively clear, mainly using state continuous multiplication and addition operations, combined with right shift and bitwise AND operations, to generate out as the result of pseudo-random numbers.

The algorithm uses a linear congruential generator , which is a more classic pseudo-random number generation method, and the details of the algorithm will not be described in detail. You can refer to the content in the hyperlink.

What I don't understand here is that the final bitwise AND operation is to clear the highest bit to 0. I don't know if it is done to keep the sign bit at 0.

4 TestBench and simulation results

`timescale 1ns / 1ps
module c_rand_tb();

reg  clk;
reg  rstn;
reg  reseed;
reg  [31:0] seed_val;
wire [15:0] out;
parameter half_cycle = 10;

initial                                                
begin                                                  
// code that executes only once                        
// insert code here --> begin                          
    clk = 0;
    forever begin
        #half_cycle clk = 1;
        #half_cycle clk = 0;
    end                                                          
// --> end                                             
$display("Running testbench");                       
end     

initial
begin
    rstn = 0;
    #5 rstn = 1;
    #10 rstn = 0;
end

initial
begin
    seed_val = 32'd65535;
end

initial
begin
    reseed = 0;
    #25 reseed = 1;
    #10 reseed = 0;
end

c_rand c_rand(
    .clk(clk),
    .rst(rstn),
    .reseed(reseed),
    .seed_val(seed_val),
    .out(out)
);




endmodule

It can be seen from the simulation results that whenever a new clock edge arrives, a new pseudo-random number will be generated. It feels more convenient to use.


This is the whole content of this issue. If you like my article, don't forget to like + bookmark + follow, and share it with your friends~

Guess you like

Origin blog.csdn.net/Alex497259/article/details/126263388