如何实现在HDL(Verilog的)硬件随机数发生器?
需要什么样的选择要考虑的?
这个问题是继自答案格式。 鼓励另外的答案和更新。
如何实现在HDL(Verilog的)硬件随机数发生器?
需要什么样的选择要考虑的?
这个问题是继自答案格式。 鼓励另外的答案和更新。
正如摩根的回答指出,这只会产生一个随机位。 在LFSR的位数只设置你多少价值得到序列重复之前。 如果你想要一个N位的随机数,你必须运行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长度参数设定为好,但这是困难得多,因为反馈抽头不遵循一个简单的模式。
这是一个TRNG(真随机数发生器),其在FPGA上工作。 它基本上是无触发器的LFSR型结构,所以它是连续运行一个组合循环。 该信号振荡混乱,当你把一些这些模块和XOR位你会得到一个真正的随机位的,因为每个组合的抖动。 你可以在运行这个最大时钟速率取决于你的FPGA,你应该用一个测试套件像积重难返,dieharder,STS或TestU01测试的随机性。
这些被称为Galois环振荡器(牙狼)。 有使用更少的功耗和面积等TRNGs,但他们技巧就操作和写,通常依靠调整延迟,使一个触发器去亚稳态。
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
一个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
选择抽头点,找出序列长度(数字的数量它重复之前)可以从该找到表 。
例如17820000的序列,30个位宽可以使用的抽头:
0x20000029 => bits "100000000000000000000000101001"
0x2000005E => bits "100000000000000000000001011110"
0x20000089 => bits "100000000000000000000010001001"
第一个将有一个反馈项:
feedback = data[29] ^ data[5] ^ data[3] ^ data[0];
如果您不确定水龙头的顺序,记住,MSB将永远是一个反馈点。 最后的(抽头)的反馈点定义了LFSR的有效长度,在此之后这纯粹是一个移位寄存器,并且对反馈序列没有影响。
如果你需要的69273666序列,你将不得不实现一个31位线性反馈移位寄存器,并选择适合您的随机数30位。
LFSR的是创建一个1位的随机数流的好办法,但如果你正在服用多个连续的比特有值之间的相关性,这是相同数量的转向加上抖动位。 如果号码被用作抖动流可能要介绍的映射层,例如交换每隔一个比特。 可替代地使用不同长度或抽头点的LFSR的每个比特。
高效的移位寄存器,LFSR计数器和长伪随机序列发生器,
由彼得·Alfke赛灵思应用笔记 。
线性反馈移位寄存器在Virtex器件,
由玛丽亚·乔治和彼得Alfke赛灵思应用笔记 。