From 559bbd966c816374f0e47ce5c28039cc74c605c4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joachim=20Stro=CC=88mbergson?= <joachim@secworks.se>
Date: Sat, 18 Jul 2015 08:55:49 +0200
Subject: Simplified the pointer handling. Fixed size of counter. Now all
 positions in the fifo is used and flags are correctly set.

---
 src/rtl/trng_csprng_fifo.v | 179 +++++++++++++++++++++++----------------------
 1 file changed, 90 insertions(+), 89 deletions(-)

(limited to 'src')

diff --git a/src/rtl/trng_csprng_fifo.v b/src/rtl/trng_csprng_fifo.v
index 1f91802..e90d23d 100644
--- a/src/rtl/trng_csprng_fifo.v
+++ b/src/rtl/trng_csprng_fifo.v
@@ -56,11 +56,12 @@ module trng_csprng_fifo(
   // Internal constant and parameter definitions.
   //----------------------------------------------------------------
   localparam FIFO_ADDR_BITS = 2;
-  localparam FIFO_ADDR_MAX  = FIFO_ADDR_BITS - 1;
-  localparam FIFO_MAX       = (2 ** FIFO_ADDR_BITS) - 1;
+  localparam FIFO_ADDR_MAX  = (2**FIFO_ADDR_BITS) - 1;
+  localparam FIFO_MAX       = (2 ** FIFO_ADDR_BITS);
 
   localparam WR_IDLE    = 0;
-  localparam WR_STORE   = 1;
+  localparam WR_WAIT    = 1;
+  localparam WR_NEXT    = 2;
   localparam WR_DISCARD = 7;
 
   localparam RD_IDLE    = 0;
@@ -71,7 +72,7 @@ module trng_csprng_fifo(
   //----------------------------------------------------------------
   // Registers including update variables and write enable.
   //----------------------------------------------------------------
-  reg [511 : 0] fifo_mem [0 : FIFO_MAX];
+  reg [511 : 0] fifo_mem [0 : FIFO_ADDR_MAX];
   reg           fifo_mem_we;
 
   reg [3 : 0] mux_data_ptr_reg;
@@ -80,26 +81,26 @@ module trng_csprng_fifo(
   reg         mux_data_ptr_rst;
   reg         mux_data_ptr_we;
 
-  reg [FIFO_ADDR_MAX : 0] rd_ptr_reg;
-  reg [FIFO_ADDR_MAX : 0] rd_ptr_new;
-  reg                     rd_ptr_inc;
-  reg                     rd_ptr_rst;
-  reg                     rd_ptr_we;
-
-  reg [FIFO_ADDR_MAX : 0] wr_ptr_reg;
-  reg [FIFO_ADDR_MAX : 0] wr_ptr_new;
-  reg                     wr_ptr_inc;
-  reg                     wr_ptr_rst;
-  reg                     wr_ptr_we;
-
-  reg [FIFO_ADDR_MAX : 0] fifo_ctr_reg;
-  reg [FIFO_ADDR_MAX : 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 [(FIFO_ADDR_BITS - 1) : 0] rd_ptr_reg;
+  reg [(FIFO_ADDR_BITS - 1) : 0] rd_ptr_new;
+  reg                            rd_ptr_inc;
+  reg                            rd_ptr_rst;
+  reg                            rd_ptr_we;
+
+  reg [(FIFO_ADDR_BITS - 1) : 0] wr_ptr_reg;
+  reg [(FIFO_ADDR_BITS - 1) : 0] wr_ptr_new;
+  reg                            wr_ptr_inc;
+  reg                            wr_ptr_rst;
+  reg                            wr_ptr_we;
+
+  reg [FIFO_ADDR_BITS : 0]       fifo_ctr_reg;
+  reg [FIFO_ADDR_BITS : 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 [31 : 0] rnd_data_reg;
 
@@ -117,6 +118,7 @@ module trng_csprng_fifo(
 
   reg          more_data_reg;
   reg          more_data_new;
+  reg          more_data_we;
 
 
   //----------------------------------------------------------------
@@ -147,8 +149,8 @@ module trng_csprng_fifo(
           fifo_mem[02]     <= {16{32'h00000000}};
           fifo_mem[03]     <= {16{32'h00000000}};
           mux_data_ptr_reg <= 4'h0;
-          rd_ptr_reg       <= {FIFO_ADDR_BITS{1'b0}};
-          wr_ptr_reg       <= {FIFO_ADDR_BITS{1'b0}};
+          rd_ptr_reg       <= {(FIFO_ADDR_BITS - 1){1'b0}};
+          wr_ptr_reg       <= {(FIFO_ADDR_BITS - 1){1'b0}};
           fifo_ctr_reg     <= {FIFO_ADDR_BITS{1'b0}};
           rnd_data_reg     <= 32'h00000000;
           rnd_syn_reg      <= 0;
@@ -158,48 +160,34 @@ module trng_csprng_fifo(
         end
       else
         begin
-          rnd_data_reg  <= muxed_data;
-          more_data_reg <= more_data_new;
+          rnd_data_reg <= muxed_data;
+
+          if (more_data_we)
+            more_data_reg <= more_data_new;
 
           if (rnd_syn_we)
-            begin
-              rnd_syn_reg <= rnd_syn_new;
-            end
+            rnd_syn_reg <= rnd_syn_new;
 
           if (fifo_mem_we)
-            begin
-              fifo_mem[wr_ptr_reg] <= csprng_data;
-            end
+            fifo_mem[wr_ptr_reg] <= csprng_data;
 
           if (mux_data_ptr_we)
-            begin
-              mux_data_ptr_reg <= mux_data_ptr_new;
-            end
+            mux_data_ptr_reg <= mux_data_ptr_new;
 
           if (rd_ptr_we)
-            begin
-              rd_ptr_reg <= rd_ptr_new;
-            end
+            rd_ptr_reg <= rd_ptr_new;
 
           if (wr_ptr_we)
-            begin
-              wr_ptr_reg <= wr_ptr_new;
-            end
+            wr_ptr_reg <= wr_ptr_new;
 
           if (fifo_ctr_we)
-            begin
-              fifo_ctr_reg <= fifo_ctr_new;
-            end
+            fifo_ctr_reg <= fifo_ctr_new;
 
           if (rd_ctrl_we)
-            begin
-              rd_ctrl_reg <= rd_ctrl_new;
-            end
+            rd_ctrl_reg <= rd_ctrl_new;
 
           if (wr_ctrl_we)
-            begin
-              wr_ctrl_reg <= wr_ctrl_new;
-            end
+            wr_ctrl_reg <= wr_ctrl_new;
         end
     end // reg_update
 
@@ -257,18 +245,16 @@ module trng_csprng_fifo(
       fifo_ctr_dec = 0;
 
       if (rd_ptr_rst)
-        rd_ptr_we  = 1;
+        begin
+          rd_ptr_new = {FIFO_ADDR_BITS{1'b0}};
+          rd_ptr_we  = 1;
+        end
 
       if (rd_ptr_inc)
         begin
-          fifo_ctr_dec  = 1;
-          if (rd_ptr_reg == FIFO_MAX)
-            rd_ptr_we  = 1;
-          else
-            begin
-              rd_ptr_new = rd_ptr_reg + 1'b1;
-              rd_ptr_we  = 1;
-            end
+          fifo_ctr_dec = 1;
+          rd_ptr_new   = rd_ptr_reg + 1'b1;
+          rd_ptr_we    =  1;
         end
     end // fifo_rd_ptr
 
@@ -280,21 +266,21 @@ module trng_csprng_fifo(
   //----------------------------------------------------------------
   always @*
     begin : fifo_wr_ptr
-      wr_ptr_new = {FIFO_ADDR_BITS{1'b0}};
-      wr_ptr_we  = 0;
+      wr_ptr_new   = {FIFO_ADDR_BITS{1'b0}};
+      wr_ptr_we    = 0;
+      fifo_ctr_inc = 0;
 
       if (wr_ptr_rst)
-        wr_ptr_we    = 1;
+        begin
+          wr_ptr_new   = {FIFO_ADDR_BITS{1'b0}};
+          wr_ptr_we    = 1;
+        end
 
       if (wr_ptr_inc)
         begin
-          if (wr_ptr_reg == FIFO_MAX)
-            wr_ptr_we  = 1;
-          else
-            begin
-              wr_ptr_new = wr_ptr_reg + 1'b1;
-              wr_ptr_we  = 1;
-            end
+          fifo_ctr_inc = 1;
+          wr_ptr_new   = wr_ptr_reg + 1'b1;
+          wr_ptr_we    = 1;
         end
     end // fifo_wr_ptr
 
@@ -326,15 +312,18 @@ module trng_csprng_fifo(
         end
 
       if (fifo_ctr_rst)
-        fifo_ctr_we = 1;
+        begin
+          fifo_ctr_new  = {FIFO_ADDR_BITS{1'b0}};
+          fifo_ctr_we = 1;
+        end
 
-      if ((fifo_ctr_inc) && (fifo_ctr_reg < FIFO_MAX))
+      if (fifo_ctr_inc)
         begin
           fifo_ctr_new = fifo_ctr_reg + 1'b1;
           fifo_ctr_we  = 1;
         end
 
-      if ((fifo_ctr_dec)  && (fifo_ctr_reg > 0))
+      if (fifo_ctr_dec)
         begin
           fifo_ctr_new = fifo_ctr_reg - 1'b1;
           fifo_ctr_we  = 1;
@@ -429,9 +418,9 @@ module trng_csprng_fifo(
       wr_ptr_inc    = 0;
       wr_ptr_rst    = 0;
       fifo_mem_we   = 0;
-      fifo_ctr_inc  = 0;
       fifo_ctr_rst  = 0;
       more_data_new = 0;
+      more_data_we  = 0;
       wr_ctrl_new   = WR_IDLE;
       wr_ctrl_we    = 0;
 
@@ -448,31 +437,43 @@ module trng_csprng_fifo(
                 if (!fifo_full)
                   begin
                     more_data_new = 1'b1;
+                    more_data_we  = 1'b1;
+                    wr_ctrl_new   = WR_WAIT;
+                    wr_ctrl_we    = 1;
                   end
-
-                if (csprng_data_valid)
+                else
                   begin
-                    wr_ctrl_new = WR_STORE;
-                    wr_ctrl_we  = 1;
+                    more_data_new = 1'b0;
+                    more_data_we  = 1'b1;
                   end
               end
           end
 
-        WR_STORE:
+        WR_WAIT:
           begin
-            fifo_mem_we  = 1;
-            wr_ptr_inc   = 1;
-            fifo_ctr_inc = 1;
-            wr_ctrl_new  = WR_IDLE;
-            wr_ctrl_we   = 1;
+            if (csprng_data_valid)
+              begin
+                fifo_mem_we = 1;
+                wr_ptr_inc  = 1;
+                wr_ctrl_new = WR_NEXT;
+                wr_ctrl_we  = 1;
+              end
+          end
+
+        WR_NEXT:
+          begin
+            more_data_new = 1'b0;
+            more_data_we  = 1'b1;
+            wr_ctrl_new   = WR_IDLE;
+            wr_ctrl_we    = 1;
           end
 
         WR_DISCARD:
           begin
-            fifo_ctr_rst     = 1;
-            wr_ptr_rst       = 1;
-            wr_ctrl_new      = WR_IDLE;
-            wr_ctrl_we       = 1;
+            fifo_ctr_rst = 1;
+            wr_ptr_rst   = 1;
+            wr_ctrl_new  = WR_IDLE;
+            wr_ctrl_we   = 1;
           end
       endcase // case (wr_ctrl_reg)
     end // wr_ctrl
-- 
cgit v1.2.3