In: Electrical Engineering
Please Create the Verilog/Vivado Code For:
An LFSR Pseudonumber generator, and the testbench for test it,
please comment and explain the answer as much as possible
if possible, post Pic of the waveform simulation!
////////////////////////////////////////////////////////////LFSR GENERATOR DESIGN/////////////////////
`timescale 1 ns/ 100 ps
//// W is width LFSR scaleable from 24 down to 4 bits
//// V is width LFSR for non uniform clocking scalable from 24 down
to 18 bit
//// g_type gausian distribution type, 0 = unimodal, 1 = bimodal,
from g_noise_out
//// u_type uniform distribution type, 0 = uniform, 1 =
ave-uniform, from u_noise_out
module LFSR_Plus #(parameter W = 16, V = 18, g_type = 0, u_type
= 1)
   (
       output   reg [W-1 :
0]       g_noise_out,
       output    reg  
[W-1 : 0]       u_noise_out,
       input    clk,
       input  
    n_reset,
       input  
    enable   );
  
////---------------- internal variables
----------------------------------
   reg       [W-1 : 0]
   rand_out;
   //// flip flops for shift registers
   reg       [W-1 :
0]   rand_ff;
   reg       [V-1 :
0]   rand_en_ff;
   //// registers for gaussian distribution, these form
bus wide shift registers
   reg     [W-1 : 0]  
temp_u_noise3;
   reg     [W-1 : 0]  
temp_u_noise2;
   reg     [W-1 : 0]  
temp_u_noise1;
   reg    [W-1 : 0]  
temp_u_noise0;
   reg    [W-1 : 0]  
temp_g_noise_nxt;
  
   //// LFSR for timing purposes to control output
   //// reg can be scaled from 18 up to 24 bit by
parameter V above
  
///////////////////////////////////////////////////////
   always @(posedge clk)
       begin
           if(n_reset ==
1'b 0)
          
        rand_en_ff[V-1 :0] <= 24'b
0011_0001_0011_0111_0110_0101;       //
seed word for timer lsfr
           else if(enable
== 1'b 1)
          
    begin
          
        case( V)
          
            24
           : rand_en_ff
<= {(rand_en_ff[7] ^ rand_en_ff[2] ^ rand_en_ff[1] ^
rand_en_ff[0]) , rand_en_ff[V-1 : 1]};  
    //   x^24 + x^23 + x^22 + x^17 +
1
          
            23
           : rand_en_ff
<= {(rand_en_ff[5] ^ rand_en_ff[0] ) , rand_en_ff[V-1 :
1]};          
           
           
           
           
           
//   x^23+ x^18 + 1
          
            22
           : rand_en_ff
<= {(rand_en_ff[1] ^ rand_en_ff[0]) , rand_en_ff[V-1 :
1]};          
           
           
           
           
           
    //   x^22+ x^21 + 1  
          
            21
           : rand_en_ff
<= {(rand_en_ff[2] ^ rand_en_ff[0]) , rand_en_ff[V-1 :
1]};          
           
           
           
           
           
    //    x^21+ x^19 + 1
          
            20
           : rand_en_ff
<= {(rand_en_ff[3] ^ rand_en_ff[0]) , rand_en_ff[V-1 :
1]};          
           
           
           
           
           
    //   x^20+ x^17 + 1
          
            19
           : rand_en_ff
<= {(rand_en_ff[15] ^ rand_en_ff[13] ^ rand_en_ff[0]) ,
rand_en_ff[V-1 : 1]};      
           
           
    //   x^19 + x^5 + x^2 + 1   
           
   
          
            default :
rand_en_ff <= {(rand_en_ff[7] ^ rand_en_ff[0]) , rand_en_ff[V-1
: 1]};          
           
           
           
           
           
    //   x^18 + x^11 + 1  
          
        endcase
          
    end
           else
          
    rand_en_ff <= rand_en_ff;
       end
   //// always block for random number generator using
LINEAR FEEDBACK SHIFT REG with polys for Maximal-length
   //// scaleable between 24 bits down to 4 bits
  
///////////////////////////////////////////////////////
   always @(posedge clk)
       begin
           if(n_reset ==
1'b 0)
          
    begin
          
        rand_ff[W-1 :0] <= 24'b
0110_0011_0111_0110_1001_1101;       //
seed for pseudo random number sequencer
          
        rand_out <= {W-1{1'b
0}};
          
    end
           else if(enable
== 1'b 1)
          
    begin
          
        case (W)
          
            24
           :  
begin
          
           
           
           
rand_ff[W-1 : 0] <= { ( rand_ff[7] ^ rand_ff[2] ^ rand_ff[1] ^
rand_ff[0]) , rand_ff[W-1 : 1] };    
            // x^24 +
x^23 + x^22 + x^17 + 1
          
           
           
            rand_out
<= rand_ff;
          
           
           
        end
          
            23
           :  
begin
          
           
           
           
rand_ff[W-1 : 0] <= { ( rand_ff[5] ^ rand_ff[0] ) , rand_ff[W-1
: 1] };            
           
           
           
           
    // x^23+ x^18 + 1
          
           
           
            rand_out
<= rand_ff;
          
           
           
        end
          
            22
           :  
begin
          
           
           
           
rand_ff[W-1 : 0] <= { ( rand_ff[1] ^ rand_ff[0] ) , rand_ff[W-1
: 1] };            
           
           
           
           
    // x^22+ x^21 + 1
          
           
           
            rand_out
<= rand_ff;      
   
          
           
           
        end
          
            21
           :  
begin
          
           
           
           
rand_ff[W-1 : 0] <= { ( rand_ff[2] ^ rand_ff[0] ), rand_ff[W-1 :
1] };           
           
           
           
            // x^21+
x^19 + 1
          
           
           
            rand_out
<= rand_ff;      
   
          
           
           
        end
          
           
20           :  
begin
          
           
           
           
rand_ff[W-1 : 0] <= { ( rand_ff[3] ^ rand_ff[0] ), rand_ff[W-1 :
1] };           
           
           
           
           
    // x^20+ x^17 + 1
          
           
           
            rand_out
<= rand_ff;          
           
           
          
           
           
        end  
           
           
           
   
          
           
19           :  
begin
          
           
           
           
rand_ff[W-1 : 0] <= { ( rand_ff[15] ^ rand_ff[13] ^ rand_ff[0]
), rand_ff[W-1 : 1] };        
           
            // x^19 +
x^5 + x^2 + 1
          
           
           
            rand_out
<= rand_ff;          
           
           
          
           
           
        end
          
           
18           :  
begin
          
           
           
           
rand_ff[W-1 : 0] <= { ( rand_ff[7] ^ rand_ff[0] ) , rand_ff[W-1
: 1] };            
           
           
           
           
    // x^18 + x^11 + 1
          
           
           
            rand_out
<= rand_ff;          
           
   
          
           
           
        end
          
            17
           :  
begin
          
           
           
           
rand_ff[W-1 : 0] <= { ( rand_ff[3] ^ rand_ff[0] ) , rand_ff[W-1
: 1] };            
           
           
           
           
    // x^17 + x^14 + 1
          
           
           
            rand_out
<= rand_ff;          
           
           
          
           
           
        end  
           
           
           
   
          
            16
           :  
begin
          
           
           
           
rand_ff[W-1 : 0] <= { ( rand_ff[5] ^ rand_ff[3] ^ rand_ff[2] ^
rand_ff[0]) , rand_ff[W-1 : 1] };    
        // x^16 + x^14 + x^13 + x^11
+ 1
          
           
           
            rand_out
<= rand_ff;          
           
           
   
          
           
           
        end
          
           
15           :  
begin
          
           
           
           
rand_ff[W-1 : 0] <= { ( rand_ff[1] ^ rand_ff[0] ), rand_ff[W-1 :
1] };           
           
           
           
           
    // x^15 + x^14 + 1
          
           
           
            rand_out
<= rand_ff;          
           
   
          
           
           
        end
          
            14
           :  
begin
          
           
           
           
rand_ff[W-1 : 0] <= { ( rand_ff[12] ^ rand_ff[2] ^ rand_ff[1] ^
rand_ff[0]), rand_ff[W-1 : 1] };    
            // x^14 +
x^13 + x^12 + x^2 + 1
          
           
           
            rand_out
<= rand_ff;          
           
       
          
           
           
        end
          
           
13           :  
begin
          
           
           
           
rand_ff[W-1 : 0] <= { ( rand_ff[5] ^ rand_ff[2] ^ rand_ff[1] ^
rand_ff[0] ), rand_ff[W-1 : 1] };       
    // x^13 + x^12 + x^11 + x^8 + 1
          
           
           
            rand_out
<= rand_ff;          
           
   
          
           
           
        end
          
            12
           :  
begin
          
           
           
           
rand_ff[W-1 : 0] <= { ( rand_ff[8] ^ rand_ff[2] ^ rand_ff[1] ^
rand_ff[0] ), rand_ff[W-1 : 1] };    
        // x^12 + x^11 + x^10 + x^4 +
1
          
           
           
            rand_out
<= rand_ff;          
           
           
   
          
           
           
        end
          
            11
           :  
begin
          
           
           
           
rand_ff[W-1 : 0] <= { ( rand_ff[1] ^ rand_ff[0] ), rand_ff[W-1 :
1] };            
           
           
           
           
    // x^11 + x^9 + 1
          
           
           
            rand_out
<= rand_ff;          
           
       
          
           
           
        end
          
            10
           :  
begin
          
           
           
           
rand_ff[W-1 : 0] <= { ( rand_ff[3] ^ rand_ff[0] ), rand_ff[W-1 :
1] };           
           
           
           
           
        // x^10 + x^7 + 1
          
           
           
            rand_out
<= rand_ff;  
          
           
           
        end
          
            9
           :  
begin
          
           
           
           
rand_ff[W-1 : 0] <= { ( rand_ff[4] ^ rand_ff[0] ), rand_ff[W-1 :
1] };           
           
           
           
           
    // x^9 + x^5 + 1
          
           
           
            rand_out
<= rand_ff;          
           
       
          
           
           
        end
          
           
8          
    :   begin
          
           
           
           
rand_ff[W-1 : 0] <= { ( rand_ff[4] ^ rand_ff[3] ^ rand_ff[2] ^
rand_ff[0]), rand_ff[W-1 : 1] };       
        // x^8 + x^6 + x^5 + x^4 +
1
          
           
           
            rand_out
<= rand_ff;          
           
       
          
           
           
        end
          
           
7          
    :   begin
          
           
           
           
rand_ff[W-1 : 0] <= { ( rand_ff[1] ^ rand_ff[0] ) , rand_ff[W-1
: 1] };           
           
           
           
           
    // x^7 + x^6 + 1
          
           
           
            rand_out
<= rand_ff;
          
           
           
        end
          
           
6          
    :   begin
          
           
           
           
rand_ff[W-1 : 0] <= { ( rand_ff[1] ^ rand_ff[0] ) , rand_ff[W-1
: 1] };           
           
           
           
            // x^6 +
x^5 + 1
          
           
           
            rand_out
<= rand_ff;          
           
       
          
           
           
        end
          
           
           
       
          
            5
           :  
begin
          
           
           
           
rand_ff[W-1 : 0] <= { ( rand_ff[2] ^ rand_ff[0] ), rand_ff[W-1 :
1] };            
           
           
           
            // x^5 +
x^3 + 1
          
           
           
            rand_out
<= rand_ff;      
          
           
           
        end
          
           
default   :   begin
          
           
           
           
rand_ff[W-1 : 0] <= { (rand_ff[1] ^ rand_ff[0]) , rand_ff[W-1 :
0]};          
           
           
           
           
        // x^4 + x^3 + 1
          
           
           
            rand_out
<= rand_ff;          
           
           
   
          
           
           
        end
          
        endcase
          
    end // end else if(enable == 1'b 1)
           else
          
    rand_out <= rand_out;
       end    // end always
   //// FIFO for inputs from rand_out, tool should
prune two msb and sign extend in adder below
  
///////////////////////////////////////////////////////  
   always @(posedge clk)
       begin
           if(n_reset ==
1'b 0)
          
    begin
          
        temp_u_noise3 <= {W-1{1'b
0}};      
          
        temp_u_noise2 <= {W-1{1'b
0}};
          
        temp_u_noise1 <= {W-1{1'b
0}};
          
        temp_u_noise0 <= {W-1{1'b
0}};
          
    end
           else if(enable
== 1'b 1)
          
    begin
          
        temp_u_noise3 <= {
rand_out[W-1] , rand_out[W-1] , rand_out[W-1 : 2] } ;  
           
        // numbers/4 are shifted
in
          
        temp_u_noise2 <=
temp_u_noise3;  
          
        temp_u_noise1 <=
temp_u_noise2;  
          
        temp_u_noise0 <=
temp_u_noise1;      
          
    end    // end if(enable == 1'b
1)  
           else
          
    begin
          
        temp_u_noise3 <=
temp_u_noise3;      
   
          
        temp_u_noise2 <=
temp_u_noise2;
          
        temp_u_noise1 <=
temp_u_noise1;
          
        temp_u_noise0 <=
temp_u_noise0;
          
    end
       end    // end of
always      
   //// always block to create distributions using the
central limit theorom, variable duty cycle time multiplexing, and
feedback
  
///////////////////////////////////////////////////////
   always @(posedge clk)
       begin
           if(enable == 1'b
1)
          
    begin
          
        case (g_type)
          
           
1          
        :  
temp_g_noise_nxt <= temp_u_noise3 + temp_u_noise2 +
temp_u_noise1 + temp_u_noise0 + g_noise_out;    
           
    // numbers in shift register are added with
feedback term for bimodal
          
           
default       :   begin
          
           
           
           
    if(rand_en_ff[9] == 1'b 1)
          
           
           
           
        temp_g_noise_nxt <=
temp_u_noise3 + temp_u_noise2 + temp_u_noise1 + temp_u_noise0 +
g_noise_out;           //
numbers in shift register are added with feedback term
          
           
           
           
    else
          
           
           
           
        temp_g_noise_nxt <=
temp_u_noise3 + temp_u_noise2 + temp_u_noise1 + temp_u_noise0;
           
           
           
    // numbers in shift register are
added          
           
           
           
       
          
           
           
            end
   // end default case
          
        endcase
          
        case (u_type)
          
           
1          
        :   begin
          
           
           
           
    if( rand_en_ff[17] == 1'b 1)
          
           
           
           
        u_noise_out <=
rand_out[W-1 : 0];      
    // average-uniform
          
           
           
           
    else
          
           
           
           
        u_noise_out <=
u_noise_out;  
          
           
           
            end
   // end case 1
          
           
default       :   u_noise_out
<= rand_out[W-1 : 0];      
            //
uniform
          
        endcase  
          
    end
           else
          
    begin
          
        temp_g_noise_nxt <=
temp_g_noise_nxt;
          
    end  
       end   // end always
  
   //// The outputs for the number generator, a timer
controls an output multiplexer
   //// g_noise_out goes through latch for feedback
  
///////////////////////////////////////////////////////  
   always @(*)
       begin
           if(n_reset ==
1'b 0)
          
    g_noise_out = {W-1{1'b 0}};
           else
if(rand_en_ff[17] == 1'b 1)
          
    g_noise_out = temp_g_noise_nxt[W-1 : 0];
           else
if(rand_en_ff[10] == 1'b 1)
          
    g_noise_out = rand_out[W-1 : 0];
           else
          
    g_noise_out = g_noise_out;  
           
       end   // end always
endmodule
//////////////////////////////////////////////////LFSR TESTBENCH///////////////////////////////////////////////
`include "LFSR_plus.v"
`timescale 1 ns/ 100 ps
module tb;
// Inputs
reg clk;
reg n_reset;
reg enable;
// Outputs
wire signed [15:0] g_noise_out;
wire signed [15:0] u_noise_out;
// Instantiate the UUT
// Please check and add your parameters manually
LFSR_Plus UUT (
.g_noise_out(g_noise_out),
.u_noise_out(u_noise_out),
.clk(clk),
.n_reset(n_reset),
.enable(enable)
);
// Initialize Inputs
// You can add your stimulus here
   integer myfileUD, myfileGD, i; // file handles
initial
begin
clk = 0;
n_reset = 0;
enable = 0;
           #200 n_reset =
1'b1;       // at time 200 release the
reset          
           #250 enable =
1'b1;         // at time 250 apply
the enable      
          
           // Open a file
for saving simulation data
           myfileUD =
$fopen ("LFSR_test_file_UD.txt");
           myfileGD =
$fopen ("LFSR_test_file_GD.txt");      
   
           // write to
file
           for(i = 0; i
< 16384; i = i+1)
          
    begin
          
        #10 $fwrite (myfileUD, "%d
\n", u_noise_out);
          
        #10 $fwrite (myfileGD, "%d
\n", g_noise_out);
          
    end
end
   always
           #10 clk = ~clk;
// every ten nanoseconds invert the clock
endmodule
//////////////////////////////////////WAVEFORM//////////////////////////////////////////////////////
