From d5974ed0d389f8953b23d98bb69b1576adad27b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joachim=20Stro=CC=88mbergson?= Date: Fri, 22 May 2015 10:34:50 +0200 Subject: (1) Added a cipher block statistics counter. (2) Cleaned up the csprng code and connected discard for fast restart of trng. (3) Added addresses for allowing API to write a known seed to allow test mode. (3) Fixed a number of minor issues during linting. (4) Fixed the csprng testbench to actually generate data as well as displaying the block stat counter. --- src/rtl/trng_csprng.v | 107 ++++++++++++++++++++------------ src/rtl/trng_csprng_fifo.v | 2 +- src/tb/fake_modules/avalanche_entropy.v | 4 +- src/tb/fake_modules/rosc_entropy.v | 6 +- src/tb/tb_csprng.v | 67 +++++++++++++------- 5 files changed, 117 insertions(+), 69 deletions(-) (limited to 'src') diff --git a/src/rtl/trng_csprng.v b/src/rtl/trng_csprng.v index eda9eea..ce5c89c 100644 --- a/src/rtl/trng_csprng.v +++ b/src/rtl/trng_csprng.v @@ -76,12 +76,32 @@ module trng_csprng( localparam ADDR_STATUS = 8'h11; localparam STATUS_RND_VALID_BIT = 0; + localparam ADDR_STAT_BLOCKS_LOW = 8'h14; + localparam ADDR_STAT_BLOCKS_HIGH = 8'h15; + localparam ADDR_RND_DATA = 8'h20; localparam ADDR_NUM_ROUNDS = 8'h40; localparam ADDR_NUM_BLOCKS_LOW = 8'h41; localparam ADDR_NUM_BLOCKS_HIGH = 8'h42; + localparam ADDR_TEST_SEED_W00 = 8'h80; + localparam ADDR_TEST_SEED_W01 = 8'h81; + localparam ADDR_TEST_SEED_W02 = 8'h82; + localparam ADDR_TEST_SEED_W03 = 8'h83; + localparam ADDR_TEST_SEED_W04 = 8'h84; + localparam ADDR_TEST_SEED_W05 = 8'h85; + localparam ADDR_TEST_SEED_W06 = 8'h86; + localparam ADDR_TEST_SEED_W07 = 8'h87; + localparam ADDR_TEST_SEED_W08 = 8'h88; + localparam ADDR_TEST_SEED_W09 = 8'h89; + localparam ADDR_TEST_SEED_W10 = 8'h8a; + localparam ADDR_TEST_SEED_W11 = 8'h8b; + localparam ADDR_TEST_SEED_W12 = 8'h8c; + localparam ADDR_TEST_SEED_W13 = 8'h8d; + localparam ADDR_TEST_SEED_W14 = 8'h8e; + localparam ADDR_TEST_SEED_W15 = 8'h8f; + localparam CIPHER_KEYLEN256 = 1'b1; // 256 bit key. localparam CIPHER_MAX_BLOCKS = 64'h1000000000000000; @@ -130,6 +150,9 @@ module trng_csprng( reg block_ctr_we; reg block_ctr_max; + reg [63 : 0] block_stat_ctr_reg; + reg [63 : 0] block_stat_ctr_new; + reg ready_reg; reg ready_new; reg ready_we; @@ -185,8 +208,6 @@ module trng_csprng( reg rnd_ack; reg fifo_cipher_data_valid; - wire [63 : 0] num_blocks; - wire muxed_rnd_ack; @@ -199,8 +220,6 @@ module trng_csprng( assign more_seed = more_seed_reg; assign debug = rnd_data[7 : 0]; assign security_error = 0; - - assign num_blocks = {num_blocks_high_reg, num_blocks_low_reg}; assign muxed_rnd_ack = rnd_ack | debug_update; @@ -259,6 +278,7 @@ module trng_csprng( cipher_ctr_reg <= {2{32'h00000000}}; cipher_block_reg <= {16{32'h00000000}}; block_ctr_reg <= {2{32'h00000000}}; + block_stat_ctr_reg <= {2{32'h00000000}}; more_seed_reg <= 0; seed_ack_reg <= 0; ready_reg <= 0; @@ -291,7 +311,10 @@ module trng_csprng( cipher_block_reg <= cipher_block_new; if (block_ctr_we) - block_ctr_reg <= block_ctr_new; + begin + block_ctr_reg <= block_ctr_new; + block_stat_ctr_reg <= block_stat_ctr_new; + end if (ready_we) ready_reg <= ready_new; @@ -378,50 +401,40 @@ module trng_csprng( case (address) // Read operations. ADDR_NAME0: - begin tmp_read_data = CORE_NAME0; - end ADDR_NAME1: - begin tmp_read_data = CORE_NAME1; - end ADDR_VERSION: - begin tmp_read_data = CORE_VERSION; - end ADDR_CTRL: - begin tmp_read_data = {30'h00000000, seed_reg, enable_reg}; - end ADDR_STATUS: - begin tmp_read_data = {30'h00000000, ready_reg, rnd_syn}; - end + + ADDR_STAT_BLOCKS_LOW: + tmp_read_data = block_stat_ctr_reg[31 : 0]; + + ADDR_STAT_BLOCKS_HIGH: + tmp_read_data = block_stat_ctr_reg[63 : 32]; ADDR_RND_DATA: begin tmp_read_data = rnd_data; - rnd_ack = 1; + rnd_ack = 1; end ADDR_NUM_ROUNDS: - begin tmp_read_data = {27'h0000000, num_rounds_reg}; - end ADDR_NUM_BLOCKS_LOW: - begin tmp_read_data = num_blocks_low_reg; - end ADDR_NUM_BLOCKS_HIGH: - begin tmp_read_data = num_blocks_high_reg; - end default: begin @@ -440,28 +453,36 @@ module trng_csprng( // ability to detect that maximum allowed number of blocks // has been reached. Either as defined by the application // or the hard coded CIPHER_MAX_BLOCKS value. + + // The stat counter is a sepatate block counter updated in + // sync with the block counter. It is only used to track the + // number of blocks generated from the cipher as a metric + // provided to the system. The stat counter is never reset. //---------------------------------------------------------------- always @* begin : block_ctr - block_ctr_new = 64'h0000000000000000; - block_ctr_we = 0; - block_ctr_max = 0; + block_ctr_new = {2{32'h00000000}}; + block_ctr_we = 1'b0; + block_ctr_max = 1'b0; + block_stat_ctr_new = {2{32'h00000000}}; if (block_ctr_rst) begin - block_ctr_new = 64'h0000000000000000; - block_ctr_we = 1; + block_ctr_new = {2{32'h00000000}}; + block_ctr_we = 1'b1; end if (block_ctr_inc) begin - block_ctr_new = block_ctr_reg + 1'b1; - block_ctr_we = 1; + block_ctr_new = block_ctr_reg + 1'b1; + block_stat_ctr_new = block_stat_ctr_reg + 1'b1; + block_ctr_we = 1; end - if ((block_ctr_reg == num_blocks) || (block_ctr_reg == CIPHER_MAX_BLOCKS)) + if ((block_ctr_reg == {num_blocks_high_reg, num_blocks_low_reg}) || + (block_ctr_reg == CIPHER_MAX_BLOCKS)) begin - block_ctr_max = 1; + block_ctr_max = 1'b1; end end // block_ctr @@ -497,7 +518,7 @@ module trng_csprng( case (csprng_ctrl_reg) CTRL_IDLE: begin - if (!enable_reg) + if (!enable_reg || discard) begin csprng_ctrl_new = CTRL_CANCEL; csprng_ctrl_we = 1; @@ -512,7 +533,7 @@ module trng_csprng( CTRL_SEED0: begin - if ((!enable_reg) || (seed_reg)) + if ((!enable_reg) || seed_reg || discard) begin csprng_ctrl_new = CTRL_CANCEL; csprng_ctrl_we = 1; @@ -529,7 +550,7 @@ module trng_csprng( CTRL_NSYN: begin - if ((!enable_reg) || (seed_reg)) + if ((!enable_reg) || seed_reg || discard) begin csprng_ctrl_new = CTRL_CANCEL; csprng_ctrl_we = 1; @@ -544,7 +565,7 @@ module trng_csprng( CTRL_SEED1: begin - if ((!enable_reg) || (seed_reg)) + if ((!enable_reg) || seed_reg || discard) begin csprng_ctrl_new = CTRL_CANCEL; csprng_ctrl_we = 1; @@ -569,7 +590,7 @@ module trng_csprng( CTRL_INIT0: begin - if ((!enable_reg) || (seed_reg)) + if ((!enable_reg) || seed_reg || discard) begin csprng_ctrl_new = CTRL_CANCEL; csprng_ctrl_we = 1; @@ -585,7 +606,7 @@ module trng_csprng( CTRL_INIT1: begin - if ((!enable_reg) || (seed_reg)) + if ((!enable_reg) || seed_reg || discard) begin csprng_ctrl_new = CTRL_CANCEL; csprng_ctrl_we = 1; @@ -599,7 +620,7 @@ module trng_csprng( CTRL_NEXT0: begin - if ((!enable_reg) || (seed_reg)) + if ((!enable_reg) || seed_reg || discard) begin csprng_ctrl_new = CTRL_CANCEL; csprng_ctrl_we = 1; @@ -613,12 +634,12 @@ module trng_csprng( end CTRL_NEXT1: - if ((!enable_reg) || (seed_reg)) + if ((!enable_reg) || seed_reg || discard) begin csprng_ctrl_new = CTRL_CANCEL; csprng_ctrl_we = 1; end - else if (cipher_ready) + else if (cipher_ready && cipher_data_out_valid) begin block_ctr_inc = 1; fifo_cipher_data_valid = 1; @@ -628,7 +649,7 @@ module trng_csprng( CTRL_MORE: begin - if ((!enable_reg) || (seed_reg)) + if ((!enable_reg) || seed_reg || discard) begin csprng_ctrl_new = CTRL_CANCEL; csprng_ctrl_we = 1; @@ -665,6 +686,10 @@ module trng_csprng( csprng_ctrl_we = 1; end + default: + begin + end + endcase // case (cspng_ctrl_reg) end // csprng_ctrl_fsm diff --git a/src/rtl/trng_csprng_fifo.v b/src/rtl/trng_csprng_fifo.v index 9c52ef5..1f91802 100644 --- a/src/rtl/trng_csprng_fifo.v +++ b/src/rtl/trng_csprng_fifo.v @@ -447,7 +447,7 @@ module trng_csprng_fifo( begin if (!fifo_full) begin - more_data_new = 1; + more_data_new = 1'b1; end if (csprng_data_valid) diff --git a/src/tb/fake_modules/avalanche_entropy.v b/src/tb/fake_modules/avalanche_entropy.v index 857926c..2caf743 100644 --- a/src/tb/fake_modules/avalanche_entropy.v +++ b/src/tb/fake_modules/avalanche_entropy.v @@ -80,9 +80,9 @@ module avalanche_entropy( .clk(clk), .reset_n(reset_n), - .enable(1), + .enable(1'b1), - .raw_entropy(noise), + .raw_entropy(), .stats(), .enabled(entropy_enabled), diff --git a/src/tb/fake_modules/rosc_entropy.v b/src/tb/fake_modules/rosc_entropy.v index b66bd90..add8b7a 100644 --- a/src/tb/fake_modules/rosc_entropy.v +++ b/src/tb/fake_modules/rosc_entropy.v @@ -41,8 +41,6 @@ module rosc_entropy( input wire clk, input wire reset_n, - input wire noise, - input wire cs, input wire we, input wire [7 : 0] address, @@ -80,9 +78,9 @@ module rosc_entropy( .clk(clk), .reset_n(reset_n), - .enable(1), + .enable(1'b1), - .raw_entropy(noise), + .raw_entropy(), .stats(), .enabled(entropy_enabled), diff --git a/src/tb/tb_csprng.v b/src/tb/tb_csprng.v index f860258..0404b56 100644 --- a/src/tb/tb_csprng.v +++ b/src/tb/tb_csprng.v @@ -55,6 +55,25 @@ module tb_csprng(); parameter CLK_HALF_PERIOD = 1; parameter CLK_PERIOD = 2 * CLK_HALF_PERIOD; + localparam ADDR_NAME0 = 8'h00; + localparam ADDR_NAME1 = 8'h01; + localparam ADDR_VERSION = 8'h02; + + localparam ADDR_CTRL = 8'h10; + localparam CTRL_ENABLE_BIT = 0; + localparam CTRL_SEED_BIT = 1; + + localparam ADDR_STATUS = 8'h11; + localparam STATUS_RND_VALID_BIT = 0; + + localparam ADDR_STAT_BLOCKS_LOW = 8'h14; + localparam ADDR_STAT_BLOCKS_HIGH = 8'h15; + + localparam ADDR_RND_DATA = 8'h20; + + localparam ADDR_NUM_ROUNDS = 8'h40; + localparam ADDR_NUM_BLOCKS_LOW = 8'h41; + localparam ADDR_NUM_BLOCKS_HIGH = 8'h42; //---------------------------------------------------------------- // Register and Wire declarations. @@ -166,17 +185,19 @@ module tb_csprng(); $display("test_mode = 0x%01x, seed = 0x%01x, enable = 0x%01x", dut.test_mode, dut.seed_reg, dut.enable_reg); $display("num_rounds = 0x%02x, num_blocks = 0x%016x", - dut.num_rounds_reg, dut.num_blocks); + dut.num_rounds_reg, {dut.num_blocks_high_reg, + dut.num_blocks_low_reg}); $display("seed_syn = 0x%01x, seed_ack = 0x%01x, seed_data = 0x%064x", dut.seed_syn, dut.seed_ack, dut.seed_data); $display(""); $display("Internal states:"); - $display("cipher_key = 0x%032x", dut.cipher_key_reg); - $display("cipher_iv = 0x%08x, cipher_ctr = 0x%08x", + $display("cipher_key = 0x%032x", dut.cipher_key_reg); + $display("cipher_iv = 0x%08x, cipher_ctr = 0x%08x", dut.cipher_iv_reg, dut.cipher_ctr_reg); - $display("cipher_block = 0x%064x", dut.cipher_block_reg); - $display("csprng_ctrl = 0x%02x", dut.csprng_ctrl_reg); + $display("cipher_block = 0x%064x", dut.cipher_block_reg); + $display("csprng_blocks = 0x%016x", dut.block_stat_ctr_reg); + $display("csprng_ctrl = 0x%02x", dut.csprng_ctrl_reg); $display(""); $display("Cipher states:"); @@ -192,7 +213,7 @@ module tb_csprng(); $display("Outputs:"); $display("rnd_syn = 0x%01x, rnd_ack = 0x%01x, rnd_data = 0x%08x", - dut.rnd_syn, dut.rnd_ack, dut.rnd_data); + dut.rnd_syn, dut.rnd_ack, tb_read_data); $display(""); end endtask // dump_dut_state @@ -203,7 +224,7 @@ module tb_csprng(); // // Write the given word to the DUT using the DUT interface. //---------------------------------------------------------------- - task write_word(input [11 : 0] address, + task write_word(input [11 : 0] address, input [31 : 0] word); begin if (DEBUG) @@ -317,25 +338,30 @@ module tb_csprng(); //---------------------------------------------------------------- - // tc1_test_init_cipher() + // tc1_init_csprng() // // TC1: Test that the DUT automatically starts initialize when - // enable is set. + // enable is set. We also starts pulling random data from the + // csprng to see that it actually emits data as expected. //---------------------------------------------------------------- - task tc1_test_init_cipher(); + task tc1_init_csprng(); begin - $display("*** TC1: Test automatic init of cipher started."); - // tb_num_blocks = 64'h0000000000000004; - tb_seed_data = {8{64'haaaaaaaa55555555}}; - // tb_num_rounds = 5'h08; - tb_rnd_ack = 1; + tc_ctr = tc_ctr + 1; + + $display("*** TC1: Test automatic init of csprng started."); + + tb_seed_data = {8{64'haaaaaaaa55555555}}; + tb_seed_syn = 1'b1; - #(2000 * CLK_PERIOD); + tb_cs = 1'b1; + tb_we = 1'b0; + tb_address = ADDR_RND_DATA; - $display("*** TC1: Test automatic init of cipher done."); + #(200 * CLK_PERIOD); + $display("*** TC1: Test automatic init of csprng done."); end - endtask // tc1_test_init_cipher + endtask // tc1_init_csprng //---------------------------------------------------------------- @@ -355,13 +381,12 @@ module tb_csprng(); reset_dut(); dump_dut_state(); - // Test code goes here. - tc1_test_init_cipher(); + tc1_init_csprng(); display_test_results(); $display(""); - $display("*** CSPRNG simulation done. ***"); + $display("*** csprng simulation done. ***"); $finish; end // csprng_test endmodule // tb_csprng -- cgit v1.2.3