/****************************************************************************************************************** * File: gene_aleatoire.v * Authors : Areabot * Date : 28/10/2005 * This program is released under the GNU Public License. * * Ce module est un générateur pseudo-aléatoire générant un nombre compris * entre period_min et (period_min + period_range) * * Variables : * - period_min[11:0] : la borne min de la periode de base * - period_range[11:0] : de combien on peut l'allonger * - i indice de boucle (sur 4 bits), * - n[11:0] : le nombre aléatoire calculé, compris entre period_min et (period_min + period_range) * - r[10:0] : un nombre aléatoire compris entre 0 et 3FF * * Algorithme : * start * i = 12 * n = 0 * r = aléatoire(0 .. 7FF) * multiplication * si (period_range[11]==1) * n = n + r * r = r >> 1 * i = i - 1 * period_range = period_range << 1 * si (i!=0) goto multiplication * fin * out = n + period_min * * Remarques : * - period_min et period_max doivent être choisis de facon telle que out tienne sur 12 bits. * C'est le cas en pratique... * - par construction, on divise la clock (au minimum) par (period_min+1) *******************************************************************************************************************/ module gene_aleatoire(clk, reset_n, period_min, period_range, out); input clk; input reset_n; input [11:0] period_min, period_range; output [11:0] out; reg [11:0] out; reg [3:0] i; reg [11:0] n; reg [10:0] r; reg [11:0] period_range_r; wire [31:0] aleat; reg [1:0] state; `define idle 2'b00 `define mult 2'b01 `define fin 2'b10 always @(posedge clk or negedge reset_n) if(~reset_n) begin n <= 0; i <= 0; r <= 0; period_range_r <= 0; out <= 0; state <= `idle; end else begin case(state) default : state <= `idle; `idle : begin n <= 0; period_range_r <= period_range; r <= aleat[10:0]; state <= `mult; i <= 12; end `mult : begin r <= {1'b0, r[10:1]}; i <= i - 1; if(period_range_r[11]) n <= n + r; period_range_r <= {period_range_r[10:0], 1'b0}; if(i==1) state <= `fin; end `fin : begin out <= n + period_min; state <= `idle; end endcase end lfsr lfsr(clk, reset_n, aleat); endmodule