Random 随机数的LSFR计数器 模块LSFR\u计数器 #(参数位=5) ( 输入时钟, 输入rst\n, 输出寄存器[4:0]数据 ); reg[4:0]数据\u下一步; 总是开始 data_next[4]=数据[4]^data[1]; data_next[3]=数据[3]^data[0]; data_next[2]=data[2]^data_next[4]; data_next[1]=data[1]^data_next[3]; data_next[0]=数据[0]^data_next[2]; 结束 始终(posedge clk或NEGDEDGE rst)开始 如果(!rst_n) data

Random 随机数的LSFR计数器 模块LSFR\u计数器 #(参数位=5) ( 输入时钟, 输入rst\n, 输出寄存器[4:0]数据 ); reg[4:0]数据\u下一步; 总是开始 data_next[4]=数据[4]^data[1]; data_next[3]=数据[3]^data[0]; data_next[2]=data[2]^data_next[4]; data_next[1]=data[1]^data_next[3]; data_next[0]=数据[0]^data_next[2]; 结束 始终(posedge clk或NEGDEDGE rst)开始 如果(!rst_n) data,random,verilog,Random,Verilog,如果您想要实现一个N位LFSR,那么因为LFSR的每个长度都有一个不同的多项式,因此有一组不同的抽头到XOR以产生下一个LFSR值,您需要有一个常量或一个查找表来描述不同的抽头点,然后设计可以基于“位”使用这些抽头点 一种更简单的方法是实现一个32位LFSR,然后使用其中最低有效的N位作为输出。除了最大长度LFSR之外,这还增加了重复周期,在这些情况下提供了更好的随机性 如果您选择第一个选项,请查看使用斐波那契形式而不是伽罗瓦形式是否会使设计以这种方式更有利于参数化。我不太清楚您在5位示例中使用

如果您想要实现一个N位LFSR,那么因为LFSR的每个长度都有一个不同的多项式,因此有一组不同的抽头到XOR以产生下一个LFSR值,您需要有一个常量或一个查找表来描述不同的抽头点,然后设计可以基于“位”使用这些抽头点


一种更简单的方法是实现一个32位LFSR,然后使用其中最低有效的N位作为输出。除了最大长度LFSR之外,这还增加了重复周期,在这些情况下提供了更好的随机性

如果您选择第一个选项,请查看使用斐波那契形式而不是伽罗瓦形式是否会使设计以这种方式更有利于参数化。我不太清楚您在5位示例中使用的是哪种形式

我是一个VHDL爱好者*,所以我不能给出Verilog代码,但类似VHDL的伪代码(未经测试)可能如下所示:

module LSFR_counter 
#(parameter BITS = 5)
(
  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_ff @(posedge clk or negedge rst_n) begin
  if(!rst_n)
    data <= 5'h1f;
  else
    data <= data_next;
end
endmodule
constant TAPS\u TABLE:TAPS\u TABLE\u type:=(
"00000011",
"00000110",
...
);
对于0到2位循环中的i
如果表(位-2)(i)=“1”),则

数据_next(i)N通常为LFSR的状态保留,M最好用于我们希望生成的随机比特数

标准LFSR生成1位随机数据,如果使用LFSR的连续位,则它们可以高度相关,尤其是在每个时钟周期采用多位值的情况下。为了消除这种相关性,我们可以对lfsr进行超频,例如4次以生成4位。另一种方法是计算每一位的方程(反馈多项式)。对于每个时钟,其内部状态(由LFSR的N位表示)将向前移动4步。这两种技术都是为了使状态向前移动一步以上而进行过时钟或创建反馈抽头,称为向前跳跃

问题中的代码示例取自,这是为leap forward lfsr手动创建额外反馈的示例

要做到这一点,可以通过生成转移矩阵,并提高到我们希望前进的步数的幂来完成

快速4位LFRS示例:带转换矩阵a:

constant TAPS_TABLE : TAPS_TABLE_type := (
    "00000011",
    "00000110",
    ...
);

for i in 0 to BITS-2 loop
    if (TAPS_TABLE(BITS-2)(i) = '1') then
        data_next(i) <= data(0) xor data(i+1)
    else
        data_next(i) <= data(i+1)
    end if;
end for;
反馈是第一位和最后一位的异或,见矩阵的最后一行。所有其他行都只是一个班次。该LFSR的输出适合一位。除非超频,否则两个比特的相关性会很高

如果我们需要两位,我们需要平方转换矩阵。可以看出,前两行是两个位置的移位,我们需要两个位置的反馈,即我们将LFSR向前移动,每个时钟有两个状态

如果我们想要三个比特,请确认:

>> a^2

ans =

     0     0     1     0
     0     0     0     1
     1     0     0     1
     1     1     0     1
上一个问题中的第二个代码示例继续对代码进行参数化,这样就不必手动创建leap forward计算,跳过了所有可爱的数学!然而,使用的方法意味着它不能完全参数化。因此,我想重温一下我为这个问题给出的例子:

a^3

ans =

     0     0     0     1
     1     0     0     1
     1     1     0     1
     1     1     1     1
模fibonacci\u lfsr(
输入时钟,
输入rst\n,
输出[4:0]数据
);
有线反馈=数据[4]^数据[1];
始终@(posedge clk或negedge rst_n)
如果(~rst_n)
数据除前面的答案外:

几年前,Xilinx写了一篇关于如何实现“伪随机数生成器”(PRNG)的好文章。AppNote有一个n=3..168的抽头表。抽头表经过优化,允许使用移位寄存器。因此,n=32的PRNG不使用32个单一FFs


“N位LFSR,因为每个LFSR都有一个不同的多项式”。。。“您需要有描述不同分接点的常数或查找表”。我不明白这背后的逻辑。为什么我们要为单个LFSR使用不同的多项式?“对于最大长度LFSR之外的任何东西”,为什么我们不构建最大长度LFSR?如果您要简单地实现一个32位LFSR,那么只需获取32位寄存器的最低有效N位,即除32位之外的“N”的任何值,即可创建不同大小的输出(本例中的最大长度)将给出一个比实现长度为N的LFSR更长的随机序列。这就是我的意思。如果您采用我提出的另一个备选方案,即生成一个LFSR,该LFSR在LFSR中具有指定数量的位(而不仅仅是输出),那么当然,代码可以产生不同大小的LFSR,每个都需要不同的点击。如果您可以链接到,那就太好了,因为包含示例的答案回答了第二个示例中的问题。但是我需要在verilog中实现LSFR。此文档不特定于任何HDL。您应该能够把所展示的原理图翻译成Verilog,是吗?
a^3

ans =

     0     0     0     1
     1     0     0     1
     1     1     0     1
     1     1     1     1
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
module fibonacci_lfsr#(
  parameter POLYNOMIAL = 4'h9
)(
  input  clk,
  input  rst_n,

  output [4:0] data
);

//AND data with POLYNOMIAL this 
// selects only the taps in the polynomial to be used.
// ^(  ) performs a XOR reduction to 1 bit
always @* begin
  feedback  = ^( POLYNOMIAL & data);
end

//Reseting to 0 is easier
// Invert feedback, all 1's state is banned instead of all 0's
always @(posedge clk or negedge rst_n)
  if (~rst_n) 
    data <= 'b0;
  else
    data <= {data[3:0], ~feedback};

endmodule
always @* begin
  data_next = data;
  feedback  = ^( POLYNOMIAL & data);
  data_next = {data_next[3:0], ~feedback} ; //<- Shift and feedback
end

always @(posedge clk or negedge rst_n)
  if (~rst_n) 
    data <= 'b0;
  else
    data <= data_next;
module fibonacci_lfsr#(
  parameter POLYNOMIAL = 4'h9,
  parameter N = 4,
  parameter BITS = 2
)(
  input  clk,
  input  rst_n,

  output [BITS-1:0] random
);
reg [N-1:0] data;
reg [N-1:0] data_next;
reg feedback;

assign random = data[N-1:N-BITS];

always @* begin
  data_next = data;
  // Compiler unrolls the loop, calculating the transition matrix
  for (int i=0; i<BITS; i++) begin
    feedback  = ^( POLYNOMIAL & data_next);
    data_next = {data_next[N-2:0], ~feedback} ; 
  end
end

always @(posedge clk or negedge rst_n)
  if (~rst_n) 
    data <= 'b0;
  else
    data <= data_next;
endmodule