Как реализовать (псевдо) аппаратный генератор случайных чисел

Как реализовать аппаратный генератор случайных чисел на HDL (verilog)?

Какие варианты необходимо рассмотреть?


Этот вопрос соответствует формату самостоятельного ответа. Дополнительные ответы и обновления приветствуются.


person Morgan    schedule 24.01.2013    source источник


Ответы (3)


Как отмечено в ответе Моргана, это даст только один случайный бит. Количество битов в 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, но это намного сложнее, поскольку отводы обратной связи не следуют простой схеме.

person nguthrie    schedule 22.11.2013
comment
как расширить этот разворот на n бит? скажем 8 бит. - person noobcoder; 17.04.2020
comment
Изменение BITS изменит количество шагов, выполняемых за каждый такт. Однако, если вам нужен 8-битный LFSR, вам придется выяснить, как его построить. В этом примечании к приложению есть таблица, в которой указаны ответвления, необходимые для разной длины: xilinx.com /support/documentation/application_notes/xapp210.pdf - person nguthrie; 17.04.2020

Это TRNG (генератор истинных случайных чисел), который работает на FPGA. Это в основном структура типа LFSR без триггеров, поэтому это комбинаторный цикл, который работает непрерывно. Сигнал колеблется хаотично, при объединении нескольких таких модулей и битов XOR получается действительно случайный бит, так как джиттер от каждого комбинируется. Максимальная тактовая частота, с которой вы можете запустить это, зависит от вашей FPGA, вы должны проверить случайность с помощью набора тестов, такого как твердолобый, несгибаемый, 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
person StanOverflow    schedule 09.10.2014
comment
Блестящий пример асинхронного TRNG для FPGA, хотелось бы попробовать на реальном HW. Однако в коде есть опечатка: «этап» следует определять как «сетевой [31:1] этап». Для устройств Altera это должно выглядеть как 'wire [31:1] stage /* synthese keep */;' - person lvd; 19.01.2015
comment
Как вы выбирали, какие биты использовать? - person danyamachine; 02.07.2018
comment
pdfs.semanticscholar.org/e5d5/ Я скопировал многочлен на странице 7, хотя я теперь видите, я пропустил термин x^23 - person StanOverflow; 10.07.2018
comment
Эта конкретная реализация проверена в HW? Если да: то какой? Потому что я пытался реализовать это на MACHXO3 и столкнулся с проблемой, что через некоторое время колебание stage[1] исчезает. Если в качестве вывода используется stage[2], колебание сохраняется, но синхронизатор всегда выводит ноль. Скорее всего, из-за того, что в течение одного такта (тактовая частота 3,02 МГц) происходит несколько переходов. Поэтому я ищу подсказки, как решить эту проблему или альтернативные реализации. - person Christian B.; 17.05.2020
comment
@Кристиан Б. Я тестировал его на Virtex 5, я не проводил длительные тесты, может быть, до 30 минут, может быть, было бы неплохо создать два экземпляра и переключаться между ними каждые X циклов и удерживать неиспользуемый в сбросе до дайте ему остыть. - person StanOverflow; 18.05.2020
comment
Причина была гораздо более неловкой: MACHXO3 поставляется с GSR, который на самом деле активен на низком уровне, а сброс в моей логике был активным на высоком уровне. Так вот синхронизатор залипал на оба уровня сброса. В настоящее время я пытаюсь проверить, проходит ли реализация MACHXO3 жесткий тест. LT;DR: это работает - я просто тупил. - person Christian B.; 19.05.2020

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 разной длины или точки ответвления для каждого бита.

Дальнейшее чтение

Эффективные регистры сдвига, счетчики LFSR и генераторы длинных псевдослучайных последовательностей,
A Заметка о приложении Xilinx от Питера Альфке
.

Сдвиговые регистры с линейной обратной связью в устройствах Virtex,
Заметка о приложении Xilinx от Марии Джордж и Питер Альфке
.

person Morgan    schedule 24.01.2013
comment
Привет, спасибо за это подробное объяснение. Однако я думаю, что в этой строке data <= {data[2:0], feedback} ; вы хотели написать data <= {data[3:0], feedback} ;. Кроме того, поскольку я публикую, не могли бы вы указать, имеет ли значение, смещаюсь ли я влево или вправо. Я думаю, что здесь вы смещаетесь влево, какая причина для этого? Спасибо - person ipunished; 26.01.2013
comment
Хорошо подмечено, вы правы насчет обратной связи, я был на 1 бит короче. Сдвиг влево/вправо определяет порядок точек касания. При смещении вправо данные [0] ДОЛЖНЫ быть точкой обратной связи, иначе вы укорачиваете последовательность повторов. Я всегда сдвигаю влево, добавляя новые данные в LSB, позиция указывает, насколько стары данные. Для метастабильности на двойном флопе я делаю reg [1:0] meta; always @(posedge clk ... meta[1:0] <= {meta[0], inp}; - person Morgan; 26.01.2013
comment
При использовании 16-битного программного LFSR для генерации 8-битных значений я нашел полезным использовать поворот вправо для одной половины и поворот влево для другой; каждое выходное значение является xor двух половин. Этот подход сгенерирует 65 535 из 65 536 возможных пар выходных байтов (для сравнения, просмотр только 8 бит LFSR сгенерирует только 512 возможных пар). - person supercat; 04.12.2013