diff options
-rw-r--r-- | src/rtl/rosc.v | 109 | ||||
-rw-r--r-- | src/rtl/rosc_entropy.v | 261 | ||||
-rw-r--r-- | src/rtl/rosc_entropy_core.v | 265 |
3 files changed, 635 insertions, 0 deletions
diff --git a/src/rtl/rosc.v b/src/rtl/rosc.v new file mode 100644 index 0000000..afcc9bf --- /dev/null +++ b/src/rtl/rosc.v @@ -0,0 +1,109 @@ +//====================================================================== +// +// rosc.v +// ------ +// Digital ring oscillator used as entropy source. Based on the +// idea of using carry chain in adders as inverter by Bernd Paysan. +// +// +// +// 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 #(parameter WIDTH = 2) + ( + input wire clk, + input wire reset_n, + + input wire we, + + input wire [(WIDTH - 1) : 0] opa, + input wire [(WIDTH - 1) : 0] opb, + + output wire dout + ); + + //---------------------------------------------------------------- + // Registers. + //---------------------------------------------------------------- + reg dout_reg; + + + //---------------------------------------------------------------- + // Wires. + //---------------------------------------------------------------- + reg [WIDTH : 0] sum; + reg cin; + + + //---------------------------------------------------------------- + // Concurrent assignment. + //---------------------------------------------------------------- + assign dout = dout_reg; + + + //---------------------------------------------------------------- + // reg_update + //---------------------------------------------------------------- + always @ (posedge clk or negedge reset_n) + begin + if (!reset_n) + begin + dout_reg <= 1'b0; + end + else + begin + if (we) + begin + dout_reg <= cin; + end + end + end + + + //---------------------------------------------------------------- + // adder_osc + // + // Adder logic that generates the oscillator. + // + // NOTE: This logic contains a combinational loop and does + // not play well with an event driven simulator. + //---------------------------------------------------------------- + always @* + begin: adder_osc + cin = ~sum[WIDTH]; + sum = opa + opb + cin; + end +endmodule // rosc + +//====================================================================== +// EOF rosc.v +//====================================================================== diff --git a/src/rtl/rosc_entropy.v b/src/rtl/rosc_entropy.v new file mode 100644 index 0000000..b407f3b --- /dev/null +++ b/src/rtl/rosc_entropy.v @@ -0,0 +1,261 @@ +//====================================================================== +// +// rosc_entropy.v +// -------------- +// Top level wrapper for the ring oscillator entropy 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( + input wire clk, + input wire reset_n, + + output wire [7 : 0] debug, + input wire debug_update, + + input wire cs, + input wire we, + input wire [7 : 0] address, + input wire [31 : 0] write_data, + output wire [31 : 0] read_data, + output wire error + ); + + + //---------------------------------------------------------------- + // Parameters. + //---------------------------------------------------------------- + parameter ADDR_CTRL = 8'h00; + parameter CTRL_ENABLE_BIT = 0; + + parameter ADDR_STATUS = 8'h01; + parameter STATUS_RND_VALID_BIT = 0; + + parameter ADDR_OPA = 8'h08; + parameter ADDR_OPB = 8'h09; + + parameter ADDR_ENTROPY = 8'h10; + parameter ADDR_RND = 8'h20; + + + //---------------------------------------------------------------- + // Registers including update variables and write enable. + //---------------------------------------------------------------- + reg en_reg; + reg en_new; + reg en_we; + + reg [31 : 0] op_a_reg; + reg [31 : 0] op_a_new; + reg op_a_we; + + reg [31 : 0] op_b_reg; + reg [31 : 0] op_b_new; + reg op_b_we; + + + //---------------------------------------------------------------- + // Wires. + //---------------------------------------------------------------- + wire [31 : 0] entropy; + + wire [31 : 0] rnd_data; + wire rnd_valid; + reg rnd_ack; + + reg [31 : 0] tmp_read_data; + reg tmp_error; + + + //---------------------------------------------------------------- + // Concurrent connectivity for ports etc. + //---------------------------------------------------------------- + assign read_data = tmp_read_data; + assign error = tmp_error; + + + //---------------------------------------------------------------- + // module instantiations. + //---------------------------------------------------------------- + rosc_entropy_core core( + .clk(clk), + .reset_n(reset_n), + + .enable(en_reg), + + .opa(op_a_reg), + .opb(op_b_reg), + + .entropy(entropy), + + .rnd_data(rnd_data), + .rnd_valid(rnd_valid), + .rnd_ack(rnd_ack), + + .debug(debug), + .debug_update(debug_update) + ); + + + //---------------------------------------------------------------- + // 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 + en_reg <= 1; + op_a_reg <= 32'h01010101; + op_a_reg <= 32'h10101010; + end + else + begin + if (en_we) + begin + en_reg <= en_new; + end + + if (op_a_we) + begin + op_a_reg <= op_a_new; + end + + if (op_b_we) + begin + op_b_reg <= op_b_new; + end + + end + end // reg_update + + + //---------------------------------------------------------------- + // api_logic + // + // Implementation of the api logic. If cs is enabled will either + // try to write to or read from the internal registers. + //---------------------------------------------------------------- + always @* + begin : api_logic + en_new = 0; + en_we = 0; + op_a_new = 0; + op_a_we = 0; + op_b_new = 0; + op_b_we = 0; + rnd_ack = 0; + tmp_read_data = 32'h00000000; + tmp_error = 0; + + if (cs) + begin + if (we) + begin + case (address) + // Write operations. + ADDR_CTRL: + begin + en_new = write_data[CTRL_ENABLE_BIT]; + en_we = 1; + end + + ADDR_OPA: + begin + op_a_new = write_data; + op_a_we = 1; + end + + ADDR_OPB: + begin + op_b_new = write_data; + op_b_we = 1; + end + + default: + begin + tmp_error = 1; + end + endcase // case (address) + end + else + begin + case (address) + ADDR_CTRL: + begin + tmp_read_data[CTRL_ENABLE_BIT] = en_reg; + end + + ADDR_STATUS: + begin + tmp_read_data[STATUS_RND_VALID_BIT] = rnd_valid; + end + + ADDR_OPA: + begin + tmp_read_data = op_a_reg; + end + + ADDR_OPB: + begin + tmp_read_data = op_b_reg; + end + + ADDR_ENTROPY: + begin + tmp_read_data = entropy; + end + + ADDR_RND: + begin + tmp_read_data = rnd_data; + rnd_ack = 1; + end + + default: + begin + tmp_error = 1; + end + endcase // case (address) + end + end + end + +endmodule // rosc_entropy_core + +//====================================================================== +// EOF rosc_entropy_core.v +//====================================================================== 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 +//====================================================================== |