7

如何在 HDL(verilog)中实现硬件随机数生成器?

需要考虑哪些选项?


本题采用自答题形式。鼓励添加答案和更新。

4

3 回答 3

13

正如摩根的回答中指出的那样,这只会产生一个随机位。LFSR 中的位数仅设置您在序列重复之前获得多少个值。如果你想要一个 N 位随机数,你必须运行 LFSR N 个周期。但是,如果您希望每个时钟周期都有一个新数字,则另一种选择是展开循环并预测 N 个周期内的数字。重复下面摩根的例子,但每个周期得到一个 5 位的数字:

module fibonacci_lfsr_5bit(
  input clk,
  input rst_n,

  output reg [4:0] data
);

reg [4:0] data_next;

always @* begin
  data_next[4] = data[4]^data[1];
  data_next[3] = data[3]^data[0];
  data_next[2] = data[2]^data_next[4];
  data_next[1] = data[1]^data_next[3];
  data_next[0] = data[0]^data_next[2];
end

always @(posedge clk or negedge rst_n)
  if(!rst_n)
    data <= 5'h1f;
  else
    data <= data_next;

endmodule

编辑:在下面添加了一个新版本,不需要你做数学。把它放在一个循环中,让综合工具找出逻辑:

module fibonacci_lfsr_nbit
   #(parameter BITS = 5)
   (
    input             clk,
    input             rst_n,

    output reg [4:0] data
    );

   reg [4:0] data_next;
   always_comb begin
      data_next = data;
      repeat(BITS) begin
         data_next = {(data_next[4]^data_next[1]), data_next[4:1]};
      end
   end

   always_ff @(posedge clk or negedge reset) begin
      if(!rst_n)
         data <= 5'h1f;
      else
         data <= data_next;
      end
   end

endmodule

我也想让 LFSR 长度参数化,但这要困难得多,因为反馈抽头不遵循简单的模式。

于 2013-11-22T12:39:22.083 回答
11

这是一个在 FPGA 上工作的 TRNG(真随机数生成器)。它基本上是一个没有触发器的 LFSR 类型的结构,所以它是一个连续运行的组合循环。信号混乱地振荡,当您组合其中几个模块和 XOR 位时,您会得到一个真正随机的位,因为来自每个组合的抖动。您可以运行的最大时钟频率取决于您的 FPGA,您应该使用 diehard、dieharder、STS 或 TestU01 等测试套件来测试随机性。

这些被称为伽罗瓦环形振荡器(GARO)。还有其他 TRNG 使用更少的功率和面积,但它们的操作和写入更复杂,通常依靠调整延迟来使触发器进入亚稳态。

module GARO (input stop,clk, reset, output random);

(* OPTIMIZE="OFF" *)                    //stop *xilinx* tools optimizing this away
wire [31:1] stage /* synthesis keep */; //stop *altera* tools optimizing this away
reg meta1, meta2;

assign random = meta2;

always@(posedge clk or negedge reset)
if(!reset)
  begin
    meta1 <= 1'b0;
    meta2 <= 1'b0;
  end
else if(clk)
  begin
    meta1 <= stage[1];
    meta2 <= meta1;
  end

assign stage[1] = ~&{stage[2] ^ stage[1],stop};
assign stage[2] = !stage[3];
assign stage[3] = !stage[4] ^ stage[1];
assign stage[4] = !stage[5] ^ stage[1];
assign stage[5] = !stage[6] ^ stage[1];
assign stage[6] = !stage[7] ^ stage[1];
assign stage[7] = !stage[8];
assign stage[8] = !stage[9] ^ stage[1];
assign stage[9] = !stage[10] ^ stage[1];
assign stage[10] = !stage[11];
assign stage[11] = !stage[12];
assign stage[12] = !stage[13] ^ stage[1];
assign stage[13] = !stage[14];
assign stage[14] = !stage[15] ^ stage[1];
assign stage[15] = !stage[16] ^ stage[1];
assign stage[16] = !stage[17] ^ stage[1];
assign stage[17] = !stage[18];
assign stage[18] = !stage[19];
assign stage[19] = !stage[20] ^ stage[1];
assign stage[20] = !stage[21] ^ stage[1];
assign stage[21] = !stage[22];
assign stage[22] = !stage[23];
assign stage[23] = !stage[24];
assign stage[24] = !stage[25];
assign stage[25] = !stage[26];
assign stage[26] = !stage[27] ^ stage[1];
assign stage[27] = !stage[28];
assign stage[28] = !stage[29];
assign stage[29] = !stage[30];
assign stage[30] = !stage[31];
assign stage[31] = !stage[1];

endmodule
于 2014-10-09T14:00:32.533 回答
7

LFSR通常是第一个停靠港。实现比较简单,一个移位寄存器与多个项 XORd 一起创建反馈项。

在考虑LFSR的实现时,需要考虑随机数的位宽和数字的可重复性。使用 N 位,最大 LFSR 将具有(2**N) - 1状态。如果没有额外的硬件,就不能使用所有零状态。

一个4 位 LFSR 示例,带有位 0 和位 4 的抽头:

module fibonacci_lfsr(
  input  clk,
  input  rst_n,

  output [4:0] data
);

wire feedback = data[4] ^ data[1] ;

always @(posedge clk or negedge rst_n)
  if (~rst_n) 
    data <= 4'hf;
  else
    data <= {data[3:0], feedback} ;

endmodule

可以从此中找到选择抽头点并找出序列长度(重复之前的数字数量) 。

例如,一个 17,820,000、30 位宽的序列可以使用 的抽头:

0x20000029 => bits "100000000000000000000000101001"   
0x2000005E => bits "100000000000000000000001011110"
0x20000089 => bits "100000000000000000000010001001"

第一个将有一个反馈项:

feedback = data[29] ^ data[5] ^ data[3] ^ data[0];

如果您不确定抽头的顺序,请记住 MSB 始终是反馈点。最后(抽头)反馈点定义了 LFSR 的有效长度,之后它只是一个移位寄存器,与反馈序列无关。

如果您需要 69,273,666 的序列,则必须实现 31 位 LFSR 并为您的随机数选择 30 位。

LFSR 是创建 1 位随机数流的好方法,但如果您采用多个连续位来表示值之间存在相关性,则它是相同的数字移位加上抖动位。如果数字被用作抖动流,您可能需要引入映射层,例如每隔一个位交换一次。或者,对每个位使用不同长度的 LFSR 或抽头点。

延伸阅读

Efficient Shift Registers, LFSR Counters, and Long Pseudo-Random Sequence Generators,
Peter Alfke 的 Xilinx 应用笔记

Virtex 器件中的线性反馈移位寄存器,
Maria George 和 Peter Alfke 的 Xilinx 应用笔记

于 2013-01-24T09:27:00.373 回答