From 4ed27b44609978e06be62853525db622fc87259a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joachim=20Str=C3=B6mbergson?= Date: Sat, 8 Oct 2022 18:37:48 +0200 Subject: [PATCH] Add new rosc based entropy source --- hw/application_fpga/core/trng/rtl/figaro.v | 166 ++++++++++++++++----- 1 file changed, 125 insertions(+), 41 deletions(-) diff --git a/hw/application_fpga/core/trng/rtl/figaro.v b/hw/application_fpga/core/trng/rtl/figaro.v index 9e28707..3f170ab 100644 --- a/hw/application_fpga/core/trng/rtl/figaro.v +++ b/hw/application_fpga/core/trng/rtl/figaro.v @@ -46,17 +46,40 @@ module figaro( localparam CORE_NAME1 = 32'h726f2020; // "ro " localparam CORE_VERSION = 32'h00000001; + localparam SAMPLE_RATE = 24'h0001000; + + + //---------------------------------------------------------------- + // Registers. + //---------------------------------------------------------------- + reg [23 : 0] sample_rate_ctr_reg; + reg [23 : 0] sample_rate_ctr_new; + + reg [4 : 0] bit_ctr_reg; + reg [4 : 0] bit_ctr_new; + reg bit_ctr_we; + + reg [63 : 0] entropy_reg; + reg [63 : 0] entropy_new; + reg entropy_we; + + reg ready_reg; + reg ready_new; + reg ready_we; + reg ready_set; + reg ready_rst; + //---------------------------------------------------------------- // Wires. //---------------------------------------------------------------- - reg core_read_entropy; - reg core_set_sample_rate; - wire [31 : 0] core_entropy; - wire core_ready; reg [31 : 0] tmp_read_data; reg tmp_ready; + /* verilator lint_off UNOPTFLAT */ + wire [31 : 0] f; + /* verilator lint_on UNOPTFLAT */ + //---------------------------------------------------------------- // Concurrent connectivity for ports etc. @@ -66,17 +89,94 @@ module figaro( //---------------------------------------------------------------- - // core instantiation. + // oscillators. + // + // 32 single inverters, each connect to itself. //---------------------------------------------------------------- - figaro_core core( - .clk(clk), - .reset_n(reset_n), - .read_entropy(core_read_entropy), - .set_sample_rate(core_set_sample_rate), - .sample_rate(write_data[23 : 0]), - .entropy(core_entropy), - .ready(core_ready) - ); + genvar i; + generate + for(i = 0 ; i < 32 ; i = i + 1) + begin: oscillators + /* verilator lint_off PINMISSING */ + (* keep *) SB_LUT4 #(.LUT_INIT(16'h1)) osc_inv (.I0(f[i]), .O(f[i])); + /* verilator lint_off PINMISSING */ + end + endgenerate + + + //--------------------------------------------------------------- + // reg_update + //--------------------------------------------------------------- + always @(posedge clk) + begin : reg_update + if (!reset_n) begin + sample_rate_ctr_reg <= 24'h0; + bit_ctr_reg <= 6'h0; + entropy_reg <= 64'h0; + ready_reg <= 1'h0; + end + else begin + sample_rate_ctr_reg <= sample_rate_ctr_new; + + if (bit_ctr_we) begin + bit_ctr_reg <= bit_ctr_new; + end + + if (entropy_we) begin + entropy_reg <= entropy_new; + end + + if (ready_we) begin + ready_reg <= ready_new; + end + end + end + + + //---------------------------------------------------------------- + // ready_logic + //---------------------------------------------------------------- + always @* + begin : ready_logic + ready_new = 1'h0; + ready_we = 1'h0; + + if (ready_set) begin + ready_new = 1'h1; + ready_we = 1'h1; + + end else if (ready_rst) begin + ready_new = 1'h0; + ready_we = 1'h1; + end + end + + + //---------------------------------------------------------------- + // entropy_logic + //---------------------------------------------------------------- + always @* + begin : entropy_logic + bit_ctr_new = 6'h0; + bit_ctr_we = 1'h0; + entropy_we = 1'h0; + ready_set = 1'h0; + + entropy_new = {entropy_reg[62 : 0], ^f}; + + sample_rate_ctr_new = sample_rate_ctr_reg + 1'h1; + if (sample_rate_ctr_reg == SAMPLE_RATE) begin + sample_rate_ctr_new = 24'h0; + entropy_we = 1'h1; + bit_ctr_new = bit_ctr_reg + 1'h1; + bit_ctr_we = 1'h1; + + if (bit_ctr_reg == 6'h3f) begin + bit_ctr_new = 6'h0; + ready_set = 1'h1; + end + end + end //---------------------------------------------------------------- @@ -86,40 +186,24 @@ module figaro( //---------------------------------------------------------------- always @* begin : api - core_read_entropy = 1'h0; - core_set_sample_rate = 1'h0; - tmp_read_data = 32'h0; - tmp_ready = 1'h0; + reg [31 : 0] entropy; + + ready_rst = 1'h0; + tmp_read_data = 32'h0; + tmp_ready = 1'h0; + + entropy = entropy_reg[63 : 32] ^ entropy_reg[31 : 0]; if (cs) begin tmp_ready = 1'h1; - - if (we) begin - if (address == ADDR_SAMPLE_RATE) begin - core_set_sample_rate = 1'h1; - end - end - - else begin - if (address == ADDR_NAME0) begin - tmp_read_data = CORE_NAME0; - end - - if (address == ADDR_NAME1) begin - tmp_read_data = CORE_NAME1; - end - - if (address == ADDR_VERSION) begin - tmp_read_data = CORE_VERSION; - end - + if (!we) begin if (address == ADDR_STATUS) begin - tmp_read_data = {31'h0, core_ready}; + tmp_read_data = {31'h0, ready_reg}; end if (address == ADDR_ENTROPY) begin - tmp_read_data = core_entropy; - core_read_entropy = 1'h1; + tmp_read_data = entropy; + ready_rst = 1'h1; end end end