From 376be260fba6b04a1552d9be4b53bfa4274a6911 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joachim=20Stro=CC=88mbergson?= Date: Thu, 20 Nov 2014 12:04:29 +0100 Subject: Reworked the csprng output fifo to really take advantage of the fact that the csprng delivers blocks of 512 bits. Removed trailing whitespaces and linted code. --- src/rtl/trng_csprng_fifo.v | 417 ++++++++++++++++++++------------------------- 1 file changed, 187 insertions(+), 230 deletions(-) diff --git a/src/rtl/trng_csprng_fifo.v b/src/rtl/trng_csprng_fifo.v index f71a152..b6ff2c1 100644 --- a/src/rtl/trng_csprng_fifo.v +++ b/src/rtl/trng_csprng_fifo.v @@ -6,33 +6,33 @@ // // // Author: Joachim Strombergson -// Copyright (c) 2014, NORDUnet A/S All rights reserved. +// Copyright (c) 2014, SUNET +// 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. +// Redistribution and use in source and binary forms, with or +// without modification, are permitted provided that the following +// conditions are met: // -// - 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. +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. // -// - 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. +// 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 -// 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. +// 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. // //====================================================================== @@ -55,8 +55,8 @@ module trng_csprng_fifo( //---------------------------------------------------------------- // Internal constant and parameter definitions. //---------------------------------------------------------------- - parameter FIFO_DEPTH = 32; - parameter FIFO_MAX = FIFO_DEPTH - 1; + parameter FIFO_DEPTH = 4; + parameter FIFO_MAX = FIFO_DEPTH - 1; parameter WR_IDLE = 0; parameter WR_WAIT = 1; @@ -71,53 +71,52 @@ module trng_csprng_fifo( //---------------------------------------------------------------- // Registers including update variables and write enable. //---------------------------------------------------------------- - reg [31 : 0] fifo_mem [0 : FIFO_MAX]; - reg fifo_mem_we; - - reg [3 : 0] mux_data_ptr_reg; - reg [3 : 0] mux_data_ptr_new; - reg mux_data_ptr_inc; - reg mux_data_ptr_rst; - reg mux_data_ptr_we; - - reg [7 : 0] wr_ptr_reg; - reg [7 : 0] wr_ptr_new; - reg wr_ptr_inc; - reg wr_ptr_rst; - reg wr_ptr_we; - - reg [7 : 0] rd_ptr_reg; - reg [7 : 0] rd_ptr_new; - reg rd_ptr_inc; - reg rd_ptr_rst; - reg rd_ptr_we; - - reg [31 : 0] rnd_data_reg; - - reg rnd_syn_reg; - reg rnd_syn_new; - reg rnd_syn_we; - - reg [2 : 0] wr_ctrl_reg; - reg [2 : 0] wr_ctrl_new; - reg wr_ctrl_we; - - reg [2 : 0] rd_ctrl_reg; - reg [2 : 0] rd_ctrl_new; - reg rd_ctrl_we; - - reg [5 : 0] fifo_ctr_reg; - reg [5 : 0] fifo_ctr_new; - reg fifo_ctr_inc; - reg fifo_ctr_dec; - reg fifo_ctr_rst; - reg fifo_ctr_we; - reg fifo_empty; - reg fifo_full; - - reg more_data_reg; - reg more_data_new; - reg more_data_we; + reg [511 : 0] fifo_mem [0 : FIFO_MAX]; + reg fifo_mem_we; + + reg [3 : 0] mux_data_ptr_reg; + reg [3 : 0] mux_data_ptr_new; + reg mux_data_ptr_inc; + reg mux_data_ptr_rst; + reg mux_data_ptr_we; + + reg [2 : 0] wr_ptr_reg; + reg [2 : 0] wr_ptr_new; + reg wr_ptr_inc; + reg wr_ptr_rst; + reg wr_ptr_we; + + reg [2 : 0] rd_ptr_reg; + reg [2 : 0] rd_ptr_new; + reg rd_ptr_inc; + reg rd_ptr_rst; + reg rd_ptr_we; + + reg [31 : 0] rnd_data_reg; + + reg rnd_syn_reg; + reg rnd_syn_new; + reg rnd_syn_we; + + reg [2 : 0] wr_ctrl_reg; + reg [2 : 0] wr_ctrl_new; + reg wr_ctrl_we; + + reg [2 : 0] rd_ctrl_reg; + reg [2 : 0] rd_ctrl_new; + reg rd_ctrl_we; + + reg [2 : 0] fifo_ctr_reg; + reg [2 : 0] fifo_ctr_new; + reg fifo_ctr_inc; + reg fifo_ctr_dec; + reg fifo_ctr_rst; + reg fifo_ctr_we; + reg fifo_empty; + reg fifo_full; + + reg more_data_reg; + reg more_data_new; //---------------------------------------------------------------- @@ -129,73 +128,47 @@ module trng_csprng_fifo( //---------------------------------------------------------------- // Concurrent connectivity for ports etc. //---------------------------------------------------------------- - assign rnd_data = rnd_data_reg; - assign rnd_syn = rnd_syn_reg; + assign rnd_data = rnd_data_reg; + assign rnd_syn = rnd_syn_reg; assign more_data = more_data_reg; //---------------------------------------------------------------- // reg_update + // + // Register update. All registers have asynchronous reset. //---------------------------------------------------------------- always @ (posedge clk or negedge reset_n) begin if (!reset_n) begin - fifo_mem[00] <= 32'h00000000; - fifo_mem[01] <= 32'h00000000; - fifo_mem[02] <= 32'h00000000; - fifo_mem[03] <= 32'h00000000; - fifo_mem[04] <= 32'h00000000; - fifo_mem[05] <= 32'h00000000; - fifo_mem[06] <= 32'h00000000; - fifo_mem[07] <= 32'h00000000; - fifo_mem[08] <= 32'h00000000; - fifo_mem[09] <= 32'h00000000; - fifo_mem[10] <= 32'h00000000; - fifo_mem[11] <= 32'h00000000; - fifo_mem[12] <= 32'h00000000; - fifo_mem[13] <= 32'h00000000; - fifo_mem[14] <= 32'h00000000; - fifo_mem[15] <= 32'h00000000; - fifo_mem[16] <= 32'h00000000; - fifo_mem[17] <= 32'h00000000; - fifo_mem[18] <= 32'h00000000; - fifo_mem[19] <= 32'h00000000; - fifo_mem[20] <= 32'h00000000; - fifo_mem[21] <= 32'h00000000; - fifo_mem[22] <= 32'h00000000; - fifo_mem[23] <= 32'h00000000; - fifo_mem[24] <= 32'h00000000; - fifo_mem[25] <= 32'h00000000; - fifo_mem[26] <= 32'h00000000; - fifo_mem[27] <= 32'h00000000; - fifo_mem[28] <= 32'h00000000; - fifo_mem[29] <= 32'h00000000; - fifo_mem[30] <= 32'h00000000; - fifo_mem[31] <= 32'h00000000; - + fifo_mem[00] <= {16{32'h00000000}}; + fifo_mem[01] <= {16{32'h00000000}}; + fifo_mem[02] <= {16{32'h00000000}}; + fifo_mem[03] <= {16{32'h00000000}}; mux_data_ptr_reg <= 4'h0; - wr_ptr_reg <= 8'h00; - rd_ptr_reg <= 8'h00; - fifo_ctr_reg <= 6'h00; + wr_ptr_reg <= 3'h0; + rd_ptr_reg <= 3'h0; + fifo_ctr_reg <= 3'h0; rnd_data_reg <= 32'h00000000; rnd_syn_reg <= 0; more_data_reg <= 0; - wr_ctrl_reg <= 3'h0; - rd_ctrl_reg <= 3'h0; + wr_ctrl_reg <= WR_IDLE; + rd_ctrl_reg <= RD_IDLE; end else begin - rnd_data_reg <= fifo_mem[rd_ptr_reg]; + rnd_data_reg <= muxed_data; + more_data_reg <= more_data_new; if (rnd_syn_we) begin - rnd_syn_reg <= rnd_syn_new; + rnd_syn_reg <= rnd_syn_new; end if (fifo_mem_we) begin - fifo_mem[wr_ptr_reg] <= muxed_data; + fifo_mem[wr_ptr_reg] <= csprng_data; end if (mux_data_ptr_we) @@ -218,52 +191,57 @@ module trng_csprng_fifo( fifo_ctr_reg <= fifo_ctr_new; end - if (more_data_we) + if (rd_ctrl_we) begin - more_data_reg <= more_data_new; + rd_ctrl_reg <= rd_ctrl_new; end if (wr_ctrl_we) begin wr_ctrl_reg <= wr_ctrl_new; end - - if (rd_ctrl_we) - begin - rd_ctrl_reg <= rd_ctrl_new; - end end end // reg_update //---------------------------------------------------------------- - // data_mux + // output_data_mux + // + // Logic that reads out a 512 bit word from the fifo memory + // and then selects a 32-bit word as output data. //---------------------------------------------------------------- always @* - begin : data_mux + begin : output_data_mux + reg [511 : 0] fifo_rd_data; + + fifo_rd_data = fifo_mem[rd_ptr_reg]; + case(mux_data_ptr_reg) - 00: muxed_data = csprng_data[031 : 000]; - 01: muxed_data = csprng_data[063 : 032]; - 02: muxed_data = csprng_data[095 : 064]; - 03: muxed_data = csprng_data[127 : 096]; - 04: muxed_data = csprng_data[159 : 128]; - 05: muxed_data = csprng_data[191 : 160]; - 06: muxed_data = csprng_data[223 : 192]; - 07: muxed_data = csprng_data[255 : 224]; - 08: muxed_data = csprng_data[287 : 256]; - 09: muxed_data = csprng_data[313 : 282]; - 10: muxed_data = csprng_data[351 : 320]; - 11: muxed_data = csprng_data[383 : 352]; - 12: muxed_data = csprng_data[415 : 384]; - 13: muxed_data = csprng_data[447 : 416]; - 14: muxed_data = csprng_data[479 : 448]; - 15: muxed_data = csprng_data[511 : 480]; + 00: muxed_data = fifo_rd_data[031 : 000]; + 01: muxed_data = fifo_rd_data[063 : 032]; + 02: muxed_data = fifo_rd_data[095 : 064]; + 03: muxed_data = fifo_rd_data[127 : 096]; + 04: muxed_data = fifo_rd_data[159 : 128]; + 05: muxed_data = fifo_rd_data[191 : 160]; + 06: muxed_data = fifo_rd_data[223 : 192]; + 07: muxed_data = fifo_rd_data[255 : 224]; + 08: muxed_data = fifo_rd_data[287 : 256]; + 09: muxed_data = fifo_rd_data[313 : 282]; + 10: muxed_data = fifo_rd_data[351 : 320]; + 11: muxed_data = fifo_rd_data[383 : 352]; + 12: muxed_data = fifo_rd_data[415 : 384]; + 13: muxed_data = fifo_rd_data[447 : 416]; + 14: muxed_data = fifo_rd_data[479 : 448]; + 15: muxed_data = fifo_rd_data[511 : 480]; endcase // case (mux_data_ptr_reg) - end // data_mux + end // output_data_mux //---------------------------------------------------------------- // mux_data_ptr + // + // Pointer for selecting output data word from the 512 bit + // word currently being read in the FIFO. //---------------------------------------------------------------- always @* begin : mux_data_ptr @@ -286,23 +264,28 @@ module trng_csprng_fifo( //---------------------------------------------------------------- // fifo_rd_ptr + // + // Pointer that selects the current 512 bit word in the FIFO + // to extract data from. //---------------------------------------------------------------- always @* begin : fifo_rd_ptr - rd_ptr_new = 8'h00; - rd_ptr_we = 0; + rd_ptr_new = 3'h0; + rd_ptr_we = 0; + fifo_ctr_dec = 0; if (rd_ptr_rst) begin - rd_ptr_new = 8'h00; + rd_ptr_new = 3'h0; rd_ptr_we = 1; end if (rd_ptr_inc) begin + fifo_ctr_dec = 1; if (rd_ptr_reg == FIFO_MAX) begin - rd_ptr_new = 8'h00; + rd_ptr_new = 3'h0; rd_ptr_we = 1; end else @@ -316,23 +299,25 @@ module trng_csprng_fifo( //---------------------------------------------------------------- // fifo_wr_ptr + // + // Pointer to where to store a new 512 bit word in the FIFO. //---------------------------------------------------------------- always @* begin : fifo_wr_ptr - wr_ptr_new = 8'h00; - wr_ptr_we = 0; + wr_ptr_new = 3'h0; + wr_ptr_we = 0; if (wr_ptr_rst) begin - wr_ptr_new = 8'h00; - wr_ptr_we = 1; + wr_ptr_new = 3'h0; + wr_ptr_we = 1; end if (wr_ptr_inc) begin if (wr_ptr_reg == FIFO_MAX) begin - wr_ptr_new = 8'h00; + wr_ptr_new = 3'h0; wr_ptr_we = 1; end else @@ -347,33 +332,34 @@ module trng_csprng_fifo( //---------------------------------------------------------------- // fifo_ctr // - // fifo counter tracks the number of elements and provides - // signals for full and empty fifo. + // fifo counter tracks the number of elements and also signals + // the csprng when more data is needed as well as applications + // that random numbers are available. //---------------------------------------------------------------- always @* begin : fifo_ctr - fifo_empty = 0; - fifo_full = 0; - fifo_ctr_new = 6'h00; - fifo_ctr_we = 0; + fifo_ctr_new = 3'h0; + fifo_ctr_we = 0; + fifo_empty = 0; + fifo_full = 0; - if (fifo_ctr_reg == FIFO_DEPTH) + if (fifo_ctr_reg == 3'h0) begin - fifo_full = 1; + fifo_empty = 1; end - if (fifo_ctr_reg < 6'h0f) + if (fifo_ctr_reg == FIFO_MAX) begin - fifo_empty = 1; + fifo_full = 1; end - if (fifo_ctr_inc) + if ((fifo_ctr_inc) && (fifo_ctr_reg < FIFO_MAX)) begin fifo_ctr_new = fifo_ctr_reg + 1'b1; fifo_ctr_we = 1; end - if (fifo_ctr_dec) + if ((fifo_ctr_dec) && (fifo_ctr_reg > 3'h0)) begin fifo_ctr_new = fifo_ctr_reg - 1'b1; fifo_ctr_we = 1; @@ -381,7 +367,7 @@ module trng_csprng_fifo( if (fifo_ctr_rst) begin - fifo_ctr_new = 6'h00; + fifo_ctr_new = 3'h0; fifo_ctr_we = 1; end end // fifo_ctr @@ -389,16 +375,19 @@ module trng_csprng_fifo( //---------------------------------------------------------------- // rd_ctrl + // + // Control FSM for reading data as requested by the consumers. //---------------------------------------------------------------- always @* begin : rd_ctrl - fifo_ctr_dec = 0; - rnd_syn_new = 0; - rnd_syn_we = 0; - rd_ptr_inc = 0; - rd_ptr_rst = 0; - rd_ctrl_new = RD_IDLE; - rd_ctrl_we = 0; + mux_data_ptr_rst = 0; + mux_data_ptr_inc = 0; + rnd_syn_new = 0; + rnd_syn_we = 0; + rd_ptr_inc = 0; + rd_ptr_rst = 0; + rd_ctrl_new = RD_IDLE; + rd_ctrl_we = 0; case (rd_ctrl_reg) RD_IDLE: @@ -431,8 +420,15 @@ module trng_csprng_fifo( begin if (rnd_ack) begin - fifo_ctr_dec = 1; - rd_ptr_inc = 1; + if (mux_data_ptr_reg == 4'hf) + begin + rd_ptr_inc = 1; + mux_data_ptr_rst = 1; + end + else + begin + mux_data_ptr_inc = 1; + end rnd_syn_new = 0; rnd_syn_we = 1; rd_ctrl_new = RD_IDLE; @@ -448,30 +444,27 @@ module trng_csprng_fifo( rd_ptr_rst = 1; rd_ctrl_new = RD_IDLE; rd_ctrl_we = 1; - end endcase // case (rd_ctrl_reg) - end // rd_ctrl //---------------------------------------------------------------- // wr_ctrl + // + // FSM for requesting data and writing new data to the fifo. //---------------------------------------------------------------- always @* begin : wr_ctrl - more_data_new = 0; - more_data_we = 0; - mux_data_ptr_rst = 0; - mux_data_ptr_inc = 0; - wr_ptr_inc = 0; - wr_ptr_rst = 0; - fifo_mem_we = 0; - fifo_ctr_inc = 0; - fifo_ctr_rst = 0; - wr_ctrl_new = WR_IDLE; - wr_ctrl_we = 0; + wr_ptr_inc = 0; + wr_ptr_rst = 0; + fifo_mem_we = 0; + fifo_ctr_inc = 0; + fifo_ctr_rst = 0; + more_data_new = 0; + wr_ctrl_new = WR_IDLE; + wr_ctrl_we = 0; case (wr_ctrl_reg) WR_IDLE: @@ -481,50 +474,18 @@ module trng_csprng_fifo( wr_ctrl_new = WR_DISCARD; wr_ctrl_we = 1; end - else if (!fifo_full) - begin - more_data_new = 1; - more_data_we = 1; - wr_ctrl_new = WR_WAIT; - wr_ctrl_we = 1; - end - end - - WR_WAIT: - begin - if (discard) - begin - wr_ctrl_new = WR_DISCARD; - wr_ctrl_we = 1; - end - else if (csprng_data_valid) - begin - more_data_new = 0; - more_data_we = 1; - mux_data_ptr_rst = 1; - wr_ctrl_new = WR_WRITE; - wr_ctrl_we = 1; - end - end - - WR_WRITE: - begin - if (discard) - begin - wr_ctrl_new = WR_DISCARD; - wr_ctrl_we = 1; - end - else if (!fifo_full) + else begin - fifo_mem_we = 1; - wr_ptr_inc = 1; - mux_data_ptr_inc = 1; - fifo_ctr_inc = 1; + if (!fifo_full) + begin + more_data_new = 1; + end - if (mux_data_ptr_new == 4'h0) + if (csprng_data_valid) begin - wr_ctrl_new = WR_IDLE; - wr_ctrl_we = 1; + fifo_mem_we = 1; + wr_ptr_inc = 1; + fifo_ctr_inc = 1; end end end @@ -532,15 +493,11 @@ module trng_csprng_fifo( WR_DISCARD: begin fifo_ctr_rst = 1; - more_data_new = 0; - more_data_we = 1; - mux_data_ptr_rst = 1; wr_ptr_rst = 1; wr_ctrl_new = WR_IDLE; wr_ctrl_we = 1; end endcase // case (wr_ctrl_reg) - end // wr_ctrl endmodule // trng_csprng_fifo -- cgit v1.2.3