rng.sv 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. //
  2. // Simple hardware random number generator
  3. //
  4. module rng
  5. #(parameter
  6. nclocks = 1, // Asynchronous clocks
  7. width = 32 // Output bus width
  8. )
  9. (
  10. // System reset and clock
  11. input rst_n,
  12. input sys_clk,
  13. input read_stb,
  14. input latch_stb,
  15. output ready,
  16. output reg [width-1:0] q,
  17. // Randomness inputs
  18. input [nclocks-1:0] clocks, // Random input synchronized to sys_clk
  19. (* keep = 1 *) inout [2:0] rngio // Unconnected pins with pullups
  20. );
  21. // Number of internal oscillators
  22. localparam n_osc = 2;
  23. wire [n_osc:1] osc;
  24. wire [n_osc:1] osc_s;
  25. //
  26. // Latch control and enable logic
  27. //
  28. reg [n_osc:1] osc_q;
  29. reg [n_osc:1] osc_e; // Edge detected
  30. typedef enum logic [2:0] {
  31. st_starting, // Powering up oscillators
  32. st_started, // Oscillators running
  33. st_strobed, // Starting strobe received
  34. st_latch, // Ending strobe received, latch output data
  35. st_ready, // Output data available
  36. st_stopped // Data available, powered down due to idle
  37. } state_t;
  38. state_t state = st_starting;
  39. // Number of ticks before shutting down
  40. localparam shutdown_ticks_lg2 = 1;
  41. reg [shutdown_ticks_lg2-1:0] shutdown_tmr;
  42. assign ready = (state == st_ready) | (state == st_stopped);
  43. wire running = (state != st_stopped);
  44. wire [width-1:0] random_data;
  45. always @(posedge sys_clk or negedge rst_n)
  46. if (~rst_n)
  47. begin
  48. state <= st_starting;
  49. osc_q <= 'b0;
  50. osc_e <= 'b0;
  51. end
  52. else
  53. begin
  54. osc_q <= ~osc_s;
  55. osc_e <= 'b0;
  56. shutdown_tmr <= 'b0;
  57. case (state)
  58. st_starting: begin
  59. osc_e <= osc_e | (osc_s & osc_q);
  60. if (&osc_e)
  61. state <= st_started;
  62. end
  63. st_started: begin
  64. if (latch_stb)
  65. state <= st_strobed;
  66. end
  67. st_strobed: begin
  68. if (latch_stb)
  69. state <= st_latch;
  70. end
  71. st_latch: begin
  72. // Wait here if read_stb is still active from previous read
  73. if (~read_stb)
  74. begin
  75. q <= random_data;
  76. state <= st_ready;
  77. end
  78. end
  79. st_ready: begin
  80. shutdown_tmr <= shutdown_tmr + latch_stb;
  81. // If shutdown_tmr is nonzero, then we have had at least
  82. // one latch_stb already while waiting here, and so we
  83. // can use that data immediately.
  84. if (read_stb)
  85. state <= |shutdown_tmr ? st_latch :
  86. latch_stb ? st_strobed : st_started;
  87. else if (latch_stb & &shutdown_tmr)
  88. state <= st_stopped;
  89. end
  90. st_stopped: begin
  91. // Data is available, but haven't been consumed for
  92. // a long time, so we have shut down the ring oscillators.
  93. // When a read happens, start them up again.
  94. if (read_stb)
  95. state <= st_starting;
  96. end
  97. endcase // case (state)
  98. end // else: !if(~rst_n)
  99. //
  100. // Internal oscillators: allow them to be stopped to save power
  101. // if we have had multiple ticks with no data accesses.
  102. //
  103. // Internal on-chip oscillator
  104. int_osc int_osc
  105. (
  106. .clkout ( osc[1] ),
  107. .oscena ( running )
  108. );
  109. // Ring oscillator using the rngio pins
  110. assign rngio[0] = ~rngio[2] & running;
  111. assign rngio[1] = ~rngio[0] & running;
  112. assign rngio[2] = ~rngio[1] & running;
  113. assign osc[2] = rngio[0];
  114. synchronizer #(.width(n_osc)) synchro
  115. (
  116. .rst_n ( 1'b1 ),
  117. .clk ( sys_clk ),
  118. .d ( osc ),
  119. .q ( osc_s )
  120. );
  121. // LFSR randomness accumulator
  122. // See http://users.ece.cmu.edu/~koopman/crc/crc36.html for
  123. // choice of polynomial. The x^poly_width term in the polynomial
  124. // is implicit.
  125. localparam poly_width = 33;
  126. localparam [poly_width-1:0] poly = 33'h0_0000_009d;
  127. localparam lsfr_max = width > poly_width ? width-1 : poly_width-1;
  128. wire lsfr_input = ^{osc_s, clocks};
  129. reg [lsfr_max:0] lsfr;
  130. always @(posedge sys_clk)
  131. lsfr <= ({lsfr[lsfr_max-1:0], lsfr_input} ^
  132. {{(lsfr_max+1){lsfr[poly_width-1]}} & poly});
  133. assign random_data = lsfr[width-1:0];
  134. endmodule // rng