aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/rtl/trng_csprng_fifo.v417
1 files 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