//====================================================================== // // fpga_entropy_core.v // ------------------- // fpga entropy generation core. // // // Author: Joachim Strombergson // Copyright (c) 2014, Secworks Sweden AB // All rights reserved. // // Redistribution and use in source and binary forms, with or // without modification, are permitted provided that the following // conditions are met: // // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // 2. 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. // // 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 OWNER 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 fpga_entropy_core( // Clock and reset. input wire clk, input wire reset_n, input wire [31 : 0] opa, input wire [31 : 0] opb, input wire update, output wire [31 : 0] rnd ); //---------------------------------------------------------------- // Registers including update variables and write enable. //---------------------------------------------------------------- reg [31 : 0] shift_reg; reg shift_we; reg [31 : 0] rnd_reg; reg [4 : 0] bit_ctr_reg; reg rnd_ctr_reg; reg bit0_reg; reg bit1_reg; reg bit_new; //---------------------------------------------------------------- // Wires. //---------------------------------------------------------------- wire dout02; wire dout03; wire dout07; wire dout13; wire dout41; wire dout43; //---------------------------------------------------------------- // Concurrent connectivity for ports etc. //---------------------------------------------------------------- assign rnd = rnd_reg; //---------------------------------------------------------------- // module instantiations. //---------------------------------------------------------------- bp_osc #(.WIDTH(2)) osc02(.clk(clk), .reset_n(reset_n), .opa(opa[1 : 0]), .opb(opb[1 : 0]), .dout(dout02) ); bp_osc #(.WIDTH(3)) osc03(.clk(clk), .reset_n(reset_n), .opa(opa[2 : 0]), .opb(opb[2 : 0]), .dout(dout03) ); bp_osc #(.WIDTH(7)) osc07(.clk(clk), .reset_n(reset_n), .opa(opa[6 : 0]), .opb(opb[6 : 0]), .dout(dout07) ); bp_osc #(.WIDTH(13)) osc13(.clk(clk), .reset_n(reset_n), .opa(opa[12 : 0]), .opb(opb[12 : 0]), .dout(dout13) ); bp_osc #(.WIDTH(41)) osc41(.clk(clk), .reset_n(reset_n), .opa({opa[8 : 0], opa[31 : 0]}), .opb({opb[8 : 0], opb[31 : 0]}), .dout(dout41) ); bp_osc #(.WIDTH(43)) osc43(.clk(clk), .reset_n(reset_n), .opa({opa[10 : 0], opa[31 : 0]}), .opb({opb[10 : 0], opb[31 : 0]}), .dout(dout43) ); //---------------------------------------------------------------- // reg_update // // Update functionality for all registers in the core. // All registers are positive edge triggered with synchronous // active low reset. All registers have write enable. //---------------------------------------------------------------- always @ (posedge clk) begin if (!reset_n) begin shift_reg <= 32'h00000000; rnd_reg <= 32'h00000000; bit_ctr_reg <= 5'h00; rnd_ctr_reg <= 1'b0; bit0_reg <= 1'b0; bit1_reg <= 1'b0; end else begin rnd_ctr_reg <= ~rnd_ctr_reg; if (rnd_ctr_reg) begin bit0_reg <= bit_new; end if (!rnd_ctr_reg) begin bit1_reg <= bit_new; end if (shift_we) begin shift_reg <= {shift_reg[30 : 0], bit0_reg}; bit_ctr_reg <= bit_ctr_reg + 1'b1; end if (bit_ctr_reg == 5'h1f) begin rnd_reg <= shift_reg; end end end // reg_update //---------------------------------------------------------------- // rnd_gen // // Logic that implements the actual random bit value generator // Note: This logic also performs von Neumann decorrelation. //---------------------------------------------------------------- always @* begin : rnd_gen shift_we = 1'b0; bit_new = dout02 ^ dout03 ^ dout07 ^ dout13 ^ dout41 ^ dout43; if (update && rnd_ctr_reg) begin shift_we = bit0_reg ^ bit1_reg; end end endmodule // fpga_entropy_core //====================================================================== // EOF fpga_entropy_core.v //======================================================================