diff --git a/stdlib/rtl/oh_random.v b/stdlib/rtl/oh_random.v index a1680ea..34962cf 100644 --- a/stdlib/rtl/oh_random.v +++ b/stdlib/rtl/oh_random.v @@ -1,49 +1,53 @@ //############################################################################# -//# Function: Random number generator +//# Function: Random number generator # //############################################################################# //# Author: Andreas Olofsson # //# License: MIT (see LICENSE file in OH! repository) # //############################################################################# module oh_random - #(parameter N = 32, //width of counter (max value) - parameter SEED = 32'haaaaaaaa //non zero number to start with + #(parameter N = 32 //support multiple of 32 for now... ) ( input clk, input nreset, //async reset - input [N-1:0] mask, //mask output (1 = active) - input en, //enable counter + input en, // enable counter + input entaps, // enable taps input + input [N-1:0] taps, // user driven taps + input [N-1:0] seed, // seed + input [N-1:0] mask, // mask output (1 = active) output [N-1:0] out //random output pulse ); - wire [N-1:0] taps_sel; - reg [N-1:0] lfsr_reg; - wire [N-1:0] lfsr_in; + // TODO: support non-multiples of 32 + reg [N-1:0] lfsr_reg[0:N/32-1]; + wire [N-1:0] lfsr_in[0:N/32-1]; + wire [N-1:0] taps_sel[0:N/32-1]; + wire [N/32-1:0] feedback; - // LFSR tap selector (TODO: complete table) + // instantiate multiple 32bit rngs + genvar i,j; generate - case(N) - 32: assign taps_sel[31:0] = 32'h80000057<<1; - endcase // case (N) + for(i=0;i<(N/32);i=i+1) begin + //taps + assign taps_sel[i] = entaps ? taps[(i+1)*32-1:i*32]: 32'h80000057 << 1; + //lfsr reg + always @(posedge clk or negedge nreset) + if(~nreset) + lfsr_reg[i] <= seed[(i+1)*32-1:i*32]; + else if(en) + lfsr_reg[i] <= lfsr_in[i]; + // feeback + assign feedback[i] = lfsr_reg[i][31]; + assign lfsr_in[i][0] = feedback[i]; + for(j=1;j<32;j=j+1) begin + assign lfsr_in[i][j] = taps_sel[i][j] ? (lfsr_reg[i][j-1] ^ feedback[i]) : + lfsr_reg[i][j-1]; + + end + assign out[(i+1)*32-1:i*32] = mask[(i+1)*32-1:i*32] & lfsr_reg[i]; + end // for (i=0;