diff options
Diffstat (limited to 'src/rtl/rosc_entropy_core.v')
-rw-r--r-- | src/rtl/rosc_entropy_core.v | 265 |
1 files changed, 265 insertions, 0 deletions
diff --git a/src/rtl/rosc_entropy_core.v b/src/rtl/rosc_entropy_core.v new file mode 100644 index 0000000..5b4b8c4 --- /dev/null +++ b/src/rtl/rosc_entropy_core.v @@ -0,0 +1,265 @@ +//====================================================================== +// +// rosc_entropy_core.v +// ------------------- +// Digitial ring oscillator based entropy generation core. +// +// +// Author: Joachim Strombergson +// Copyright (c) 2014, NORDUnet A/S All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// - Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// - Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// - Neither the name of the NORDUnet nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +//====================================================================== + +module rosc_entropy_core( + input wire clk, + input wire reset_n, + + input wire enable, + + input wire [31 : 0] opa, + input wire [31 : 0] opb, + + output [31 : 0] entropy, + + output wire [31 : 0] rnd_data, + output wire rnd_valid, + input wire rnd_ack, + + output wire [7 : 0] debug, + input wire debug_update + ); + + + //---------------------------------------------------------------- + // Parameters. + //---------------------------------------------------------------- + parameter NUM_SHIFT_BITS = 8'h20; + parameter SAMPLE_CLK_CYCLES = 8'hff; + + + //---------------------------------------------------------------- + // Registers including update variables and write enable. + //---------------------------------------------------------------- + reg [31 : 0] ent_shift_reg; + reg [31 : 0] ent_shift_new; + + reg ent_shift_we_reg; + reg ent_shift_we_new; + + reg [31 : 0] rnd_reg; + reg rnd_we; + + reg rnd_valid_reg; + reg rnd_valid_new; + reg rnd_valid_we; + + reg bit_we_reg; + reg bit_we_new; + + reg [7 : 0] bit_ctr_reg; + reg [7 : 0] bit_ctr_new; + reg bit_ctr_inc; + reg bit_ctr_we; + + reg [7 : 0] sample_ctr_reg; + reg [7 : 0] sample_ctr_new; + + reg [7 : 0] debug_reg; + reg debug_update_reg; + + + //---------------------------------------------------------------- + // Wires. + //---------------------------------------------------------------- + reg rosc_we; + wire [31 : 0] rosc_dout; + + + //---------------------------------------------------------------- + // Concurrent connectivity for ports etc. + //---------------------------------------------------------------- + assign entropy = ent_shift_reg; + assign rnd_data = rnd_reg; + assign rnd_valid = rnd_valid_reg; + assign debug = debug_reg; + + + //---------------------------------------------------------------- + // module instantiations. + // + // 32 1-bit wide oscillators. We want them to run as fast as + // possible to maximize differences over time. + //---------------------------------------------------------------- + genvar i; + generate + for(i = 0 ; i < 32 ; i = i + 1) + begin: oscillators + rosc #(.WIDTH(1)) osc_array(.clk(clk), + .we(rosc_we), + .reset_n(reset_n), + .opa(opa), + .opb(opb), + .dout(rosc_dout[i]) + ); + end + endgenerate + + + //---------------------------------------------------------------- + // reg_update + // + // Update functionality for all registers in the core. + // All registers are positive edge triggered with asynchronous + // active low reset. + //---------------------------------------------------------------- + always @ (posedge clk or negedge reset_n) + begin + if (!reset_n) + begin + ent_shift_reg <= 32'h00000000; + ent_shift_we_reg <= 0; + rnd_reg <= 32'h00000000; + rnd_valid_reg <= 0; + bit_ctr_reg <= 8'h00; + sample_ctr_reg <= 8'h00; + debug_reg <= 8'h00; + debug_update_reg <= 0; + end + else + begin + sample_ctr_reg <= sample_ctr_new; + ent_shift_we_reg <= ent_shift_we_new; + debug_update_reg <= debug_update; + + if (ent_shift_we_reg) + begin + ent_shift_reg <= ent_shift_new; + end + + if (bit_ctr_we) + begin + bit_ctr_reg <= bit_ctr_new; + end + + if (rnd_we) + begin + rnd_reg <= ent_shift_reg; + end + + if (rnd_valid_we) + begin + rnd_valid_reg <= rnd_valid_new; + end + + if (debug_update_reg) + begin + debug_reg <= rnd_reg[7 : 0]; + end + end + end // reg_update + + + //---------------------------------------------------------------- + // rnd_out + // + // Logic that implements the random output control. If we have + // added more than NUM_SHIFT_BITS we raise the rnd_valid flag. + // When we detect and ACK, the valid flag is dropped. + //---------------------------------------------------------------- + always @* + begin : rnd_out + bit_ctr_new = 8'h00; + bit_ctr_we = 0; + rnd_we = 0; + rnd_valid_new = 0; + rnd_valid_we = 0; + + if (bit_ctr_inc) + begin + + if (bit_ctr_reg < NUM_SHIFT_BITS) + begin + bit_ctr_new = bit_ctr_reg + 1'b1; + bit_ctr_we = 1; + end + else + begin + rnd_we = 1; + rnd_valid_new = 1; + rnd_valid_we = 1; + end + end + + if (rnd_ack) + begin + bit_ctr_new = 8'h00; + bit_ctr_we = 1; + rnd_valid_new = 0; + rnd_valid_we = 1; + end + end + + + //---------------------------------------------------------------- + // rnd_gen + // + // Logic that implements the actual random bit value generator + // by XOR mixing the oscillator outputs. These outputs are + // sampled once every SAMPLE_CLK_CYCLES. + // + // Note that the update of the shift register is delayed + // one cycle to allow the outputs from the oscillators + // to be updated. + //---------------------------------------------------------------- + always @* + begin : rnd_gen + reg ent_bit; + + bit_ctr_inc = 0; + rosc_we = 0; + ent_shift_we_new = 0; + + ent_bit = ^rosc_dout; + ent_shift_new = {ent_shift_reg[30 : 0], ent_bit}; + + sample_ctr_new = sample_ctr_reg + 1'b1; + + if (enable && (sample_ctr_reg == SAMPLE_CLK_CYCLES)) + begin + sample_ctr_new = 8'h00; + bit_ctr_inc = 1; + rosc_we = 1; + ent_shift_we_new = 1; + end + end +endmodule // rosc_entropy_core + +//====================================================================== +// EOF rosc_entropy_core.v +//====================================================================== |