aboutsummaryrefslogblamecommitdiff
path: root/src/rtl/trng_mixer.v
blob: 06e014a035966f30866468f433b41807e1b3eeb2 (plain) (tree)
1
2
3
4
5
6
7
8
9







                                                                        
                                   
                       
  
























                                                                           



                                                                        











                                                   
                                                       
 
                                                  
 



                                                         
 



                                                         
 



                                                         


                                                  



                                                    





                                                                    


















                                     



                                           
                                            

                                        
                                            


                                                  
 



                                                    



                                                                    
                                  






                           



                                       










                                       











                             






                          
                             
 




                                                                    
                                
                               
                             



                            



                                       




                                    



                                   

                            



                                                                    
                                        

                                    
 
                                  

                                 







                                                                                   
 
                                  
                                      
 



                                         

                       



                                                                    






                                            
 

                                                               
 
                                           
 



                                                        





                                                                    

                                                                

                                                                    


                      

                   


                                          


                                            
                                        
                                        

                                                              

                                                


             

                                     

                                                     
 
                           
                                           

                          
                                         

                          
                                         
 
                                      
                                                                 
 
                        
                                     
 
                            
                                             

                                 
                                                       

                                     
                                                               


                     





                                                                    

                              


                                       
                                         
                              














                                                                     





                                                             











                                       








                                                 

                                
                                                                            



                                  
                                                 
                     
 

                                   
                                                                 











                                       
                                                                    
                         
    


                                                               


                                                                    






                                   
                                       

                                   








                                              
                                             






                                                        
                            















                                                                    










                                                                  


                       
                                                 








                                                            
                            
























                                                            
                            















                                                                    










                                                                  











                                                            
                            























                                                            
                            















                                                                    










                                                                  











                                                            
                            






















                                                            



                                                                    

































                                                                    



























                                                                    





                         
                         





                                 
                          
                   
                                   








                                              
                          
                   
                                           



                                   
                               



                                              




                 
                          
                   
                                           


















                                          
                          
                   
                                           













                                          
                          
                   
                                           












                                           
                          
                   
                                           



                                   
                                   






                                              







                                                                        
//======================================================================
//
// trng_mixer.v
// ------------
// Mixer for the TRNG.
//
//
// Author: Joachim Strombergson
// Copyright (c) 2014, NORDUnet A/S
// 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.
//
// - 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.
//
// - 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.
//
// 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.
//
//======================================================================

module trng_mixer(
                  input wire            clk,
                  input wire            reset_n,

                  input wire            cs,
                  input wire            we,
                  input wire  [7 : 0]   address,
                  input wire  [31 : 0]  write_data,
                  output wire [31 : 0]  read_data,
                  output wire           error,

                  input wire            discard,
                  input wire            test_mode,
                  output wire           security_error,

                  input wire            more_seed,

                  input wire            entropy0_enabled,
                  input wire            entropy0_syn,
                  input wire [31 : 0]   entropy0_data,
                  output wire           entropy0_ack,

                  input wire            entropy1_enabled,
                  input wire            entropy1_syn,
                  input wire [31 : 0]   entropy1_data,
                  output wire           entropy1_ack,

                  input wire            entropy2_enabled,
                  input wire            entropy2_syn,
                  input wire [31 : 0]   entropy2_data,
                  output wire           entropy2_ack,

                  output wire [511 : 0] seed_data,
                  output wire           seed_syn,
                  input wire            seed_ack,

                  output wire [7 : 0]   debug,
                  input wire            debug_update
                 );


  //----------------------------------------------------------------
  // Internal constant and parameter definitions.
  //----------------------------------------------------------------
  localparam MODE_SHA_512 = 2'h3;

  localparam ENTROPY_IDLE     = 4'h0;
  localparam ENTROPY_SRC0     = 4'h1;
  localparam ENTROPY_SRC0_ACK = 4'h2;
  localparam ENTROPY_SRC1     = 4'h3;
  localparam ENTROPY_SRC1_ACK = 4'h4;
  localparam ENTROPY_SRC2     = 4'h5;
  localparam ENTROPY_SRC2_ACK = 4'h6;
  localparam TEST_ENTROPY     = 4'he;
  localparam TEST_ENTROPY_ACK = 4'hf;

  localparam CTRL_IDLE    = 4'h0;
  localparam CTRL_COLLECT = 4'h1;
  localparam CTRL_MIX     = 4'h2;
  localparam CTRL_SYN     = 4'h3;
  localparam CTRL_ACK     = 4'h4;
  localparam CTRL_NEXT    = 4'h5;

  localparam ADDR_NAME0            = 8'h00;
  localparam ADDR_NAME1            = 8'h01;
  localparam ADDR_VERSION          = 8'h02;

  localparam ADDR_MIXER_CTRL        = 8'h08;
  localparam MIXER_CTRL_ENABLE_BIT  = 0;
  localparam MIXER_CTRL_RESTART_BIT = 1;
  localparam ADDR_MIXER_STATUS      = 8'h09;
  localparam ADDR_MIXER_TIMEOUT     = 8'h20;

  localparam DEFAULT_ENTROPY_TIMEOUT = 24'h100000;

  parameter CORE_NAME0     = 32'h726e676d; // "rngm"
  parameter CORE_NAME1     = 32'h69786572; // "ixer"
  parameter CORE_VERSION   = 32'h302e3530; // "0.50"


  //----------------------------------------------------------------
  // Registers including update variables and write enable.
  //----------------------------------------------------------------
  reg [31 : 0] block_mem [0 : 31];

  reg [4 : 0] word_ctr_reg;
  reg [4 : 0] word_ctr_new;
  reg         word_ctr_inc;
  reg         word_ctr_rst;
  reg         word_ctr_we;

  reg [3 : 0] entropy_collect_ctrl_reg;
  reg [3 : 0] entropy_collect_ctrl_new;
  reg         entropy_collect_ctrl_we;

  reg [23 : 0] entropy_timeout_ctr_reg;
  reg [23 : 0] entropy_timeout_ctr_new;
  reg          entropy_timeout_ctr_inc;
  reg          entropy_timeout_ctr_rst;
  reg          entropy_timeout_ctr_we;
  reg          entropy_timeout;

  reg [23 : 0] entropy_timeout_reg;
  reg [23 : 0] entropy_timeout_new;
  reg          entropy_timeout_we;

  reg [3 : 0] mixer_ctrl_reg;
  reg [3 : 0] mixer_ctrl_new;
  reg         mixer_ctrl_we;

  reg         seed_syn_reg;
  reg         seed_syn_new;
  reg         seed_syn_we;

  reg         init_done_reg;
  reg         init_done_new;
  reg         init_done_we;

  reg         enable_reg;
  reg         enable_new;
  reg         enable_we;

  reg         restart_reg;
  reg         restart_new;

  reg [31 : 0] tmp_read_data;


  //----------------------------------------------------------------
  // Wires.
  //----------------------------------------------------------------
  reg [31 : 0]    muxed_entropy;
  reg             collect_block;
  reg             update_block;
  reg             block_done;

  reg             hash_init;
  reg             hash_next;

  wire            hash_work_factor;
  wire [31 : 0]   hash_work_factor_num;


  wire [1023 : 0] hash_block;
  wire            hash_ready;
  wire [511 : 0]  hash_digest;
  wire            hash_digest_valid;

  reg             tmp_entropy0_ack;
  reg             tmp_entropy1_ack;
  reg             tmp_entropy2_ack;

  reg             tmp_error;


  //----------------------------------------------------------------
  // Concurrent connectivity for ports etc.
  //----------------------------------------------------------------
  assign read_data      = tmp_read_data;
  assign error          = tmp_error;
  assign security_error = 0;

  assign seed_syn  = seed_syn_reg;
  assign seed_data = hash_digest;

  assign hash_block = {block_mem[00], block_mem[01], block_mem[02], block_mem[03],
                       block_mem[04], block_mem[05], block_mem[06], block_mem[07],
                       block_mem[08], block_mem[09], block_mem[10], block_mem[11],
                       block_mem[12], block_mem[13], block_mem[14], block_mem[15],
                       block_mem[16], block_mem[17], block_mem[18], block_mem[19],
                       block_mem[20], block_mem[21], block_mem[22], block_mem[23],
                       block_mem[24], block_mem[25], block_mem[26], block_mem[27],
                       block_mem[28], block_mem[29], block_mem[30], block_mem[31]};

  assign hash_work_factor     = 0;
  assign hash_work_factor_num = 32'h0;

  assign entropy0_ack = tmp_entropy0_ack;
  assign entropy1_ack = tmp_entropy1_ack;
  assign entropy2_ack = tmp_entropy2_ack;

  assign debug = 8'h55;


  //----------------------------------------------------------------
  // core instantiation.
  //----------------------------------------------------------------
  sha512_core hash_inst(
                        .clk(clk),
                        .reset_n(reset_n),

                        .init(hash_init),
                        .next(hash_next),
                        .mode(MODE_SHA_512),

                        .work_factor(hash_work_factor),
                        .work_factor_num(hash_work_factor_num),

                        .block(hash_block),

                        .ready(hash_ready),
                        .digest(hash_digest),
                        .digest_valid(hash_digest_valid)
                       );


  //----------------------------------------------------------------
  // reg_update
  //
  // Update functionality for all registers in the core.
  // All registers are positive edge triggered with asynchronous
  // active low reset.
  //----------------------------------------------------------------
  always @ (posedge clk or negedge reset_n)
    begin : reg_update
      integer i;

      if (!reset_n)
        begin
          for (i = 0 ; i < 32 ; i = i + 1)
            block_mem[i] <= 32'h0;

          init_done_reg            <= 0;
          word_ctr_reg             <= 5'h00;
          seed_syn_reg             <= 0;
          enable_reg               <= 1;
          restart_reg              <= 0;
          entropy_timeout_reg      <= DEFAULT_ENTROPY_TIMEOUT;
          entropy_timeout_ctr_reg  <= 24'h000000;
          entropy_collect_ctrl_reg <= CTRL_IDLE;
          mixer_ctrl_reg           <= CTRL_IDLE;
        end
      else
        begin
          restart_reg <= restart_new;

          if (update_block)
            block_mem[word_ctr_reg] <= muxed_entropy;

          if (init_done_we)
            init_done_reg <= init_done_new;

          if (word_ctr_we)
            word_ctr_reg <= word_ctr_new;

          if (seed_syn_we)
            seed_syn_reg <= seed_syn_new;

          if (entropy_collect_ctrl_we)
            entropy_collect_ctrl_reg <= entropy_collect_ctrl_new;

          if (enable_we)
            enable_reg <= enable_new;

          if (mixer_ctrl_we)
            mixer_ctrl_reg <= mixer_ctrl_new;

          if (entropy_timeout_we)
            entropy_timeout_reg <= entropy_timeout_new;

          if (entropy_timeout_ctr_we)
            entropy_timeout_ctr_reg <= entropy_timeout_ctr_new;
        end
    end // reg_update


  //----------------------------------------------------------------
  // mixer_api_logic
  //----------------------------------------------------------------
  always @*
    begin : mixer_api_logic
      enable_new          = 0;
      enable_we           = 0;
      restart_new         = 0;
      entropy_timeout_new = 24'h000000;
      entropy_timeout_we  = 0;
      tmp_read_data       = 32'h00000000;
      tmp_error           = 0;

      if (cs)
        begin
          if (we)
            begin
              // Write operations.
              case (address)
                // Write operations.
                ADDR_MIXER_CTRL:
                  begin
                    enable_new  = write_data[MIXER_CTRL_ENABLE_BIT];
                    enable_we   = 1;
                    restart_new = write_data[MIXER_CTRL_RESTART_BIT];
                  end

                ADDR_MIXER_TIMEOUT:
                  begin
                    entropy_timeout_new = write_data[23 : 0];
                    entropy_timeout_we  = 1;
                  end

                default:
                  begin
                    tmp_error = 1;
                  end
              endcase // case (address)
            end // if (we)

          else
            begin
              // Read operations.
              case (address)
                // Read operations.
                ADDR_NAME0:
                    tmp_read_data = CORE_NAME0;

                ADDR_NAME1:
                    tmp_read_data = CORE_NAME1;

                ADDR_VERSION:
                    tmp_read_data = CORE_VERSION;

                ADDR_MIXER_CTRL:
                  begin
                    tmp_read_data = {30'h00000000, restart_reg, enable_reg};
                  end

                ADDR_MIXER_STATUS:
                  begin
                    tmp_read_data = 32'h00000000;
                  end

                ADDR_MIXER_TIMEOUT:
                  begin
                    tmp_read_data = {8'h00, entropy_timeout_reg};
                  end

                default:
                  begin
                    tmp_error = 1;
                  end
              endcase // case (address)
            end
        end
    end // mixer_api_logic


  //----------------------------------------------------------------
  // entropy_collect_ctrl
  //
  // This FSM implements a round-robin mux for signals from the
  // entropy sources and updates the block until a block has
  // been filled.
  //----------------------------------------------------------------
  always @*
    begin : entropy_mux
      tmp_entropy0_ack         = 0;
      tmp_entropy1_ack         = 0;
      tmp_entropy2_ack         = 0;
      word_ctr_inc             = 0;
      word_ctr_rst             = 0;
      update_block             = 0;
      block_done               = 0;
      muxed_entropy            = 32'h0;
      entropy_timeout_ctr_inc  = 0;
      entropy_timeout_ctr_rst  = 0;
      entropy_collect_ctrl_new = ENTROPY_IDLE;
      entropy_collect_ctrl_we  = 0;

      case (entropy_collect_ctrl_reg)
        ENTROPY_IDLE:
          begin
            if (collect_block)
              begin
                word_ctr_rst             = 1;
                entropy_timeout_ctr_rst  = 1;
                entropy_collect_ctrl_new = ENTROPY_SRC0;
                entropy_collect_ctrl_we  = 1;
              end
          end

        ENTROPY_SRC0:
          begin
            if (!enable_reg)
              begin
                word_ctr_rst             = 1;
                entropy_collect_ctrl_new = ENTROPY_IDLE;
                entropy_collect_ctrl_we  = 1;
              end
            else
              begin
                if (entropy0_enabled)
                  begin
                    if (entropy0_syn)
                      begin
                        muxed_entropy            = entropy0_data;
                        update_block             = 1;
                        entropy_collect_ctrl_new = ENTROPY_SRC0_ACK;
                        entropy_collect_ctrl_we  = 1;
                      end
                    else
                      if (entropy_timeout)
                        begin
                          entropy_timeout_ctr_rst  = 1;
                          entropy_collect_ctrl_new = ENTROPY_SRC1;
                          entropy_collect_ctrl_we  = 1;
                        end
                      else
                        begin
                          entropy_timeout_ctr_inc = 1;
                        end
                  end
                else
                  begin
                    entropy_timeout_ctr_rst  = 1;
                    entropy_collect_ctrl_new = ENTROPY_SRC1;
                    entropy_collect_ctrl_we  = 1;
                  end
              end
          end

        ENTROPY_SRC0_ACK:
          begin
            tmp_entropy0_ack = 1;
            if (!enable_reg)
              begin
                word_ctr_rst             = 1;
                entropy_collect_ctrl_new = ENTROPY_IDLE;
                entropy_collect_ctrl_we  = 1;
              end
            else
              begin
                if (word_ctr_reg == 5'h1f)
                  begin
                    block_done               = 1;
                    entropy_collect_ctrl_new = ENTROPY_IDLE;
                    entropy_collect_ctrl_we  = 1;
                  end
                else
                  begin
                    word_ctr_inc             = 1;
                    entropy_collect_ctrl_new = ENTROPY_SRC1;
                    entropy_collect_ctrl_we  = 1;
                  end
              end
          end


        ENTROPY_SRC1:
          begin
            if (!enable_reg)
              begin
                word_ctr_rst             = 1;
                entropy_collect_ctrl_new = ENTROPY_IDLE;
                entropy_collect_ctrl_we  = 1;
              end
            else
              begin
                if (entropy1_enabled)
                  begin
                    if (entropy1_syn)
                      begin
                        muxed_entropy            = entropy1_data;
                        update_block             = 1;
                        entropy_collect_ctrl_new = ENTROPY_SRC1_ACK;
                        entropy_collect_ctrl_we  = 1;
                      end
                    else
                      if (entropy_timeout)
                        begin
                          entropy_timeout_ctr_rst  = 1;
                          entropy_collect_ctrl_new = ENTROPY_SRC2;
                          entropy_collect_ctrl_we  = 1;
                        end
                      else
                        begin
                          entropy_timeout_ctr_inc = 1;
                        end
                  end
                else
                  begin
                    entropy_collect_ctrl_new = ENTROPY_SRC2;
                    entropy_collect_ctrl_we  = 1;
                  end
              end
          end

        ENTROPY_SRC1_ACK:
          begin
            tmp_entropy1_ack = 1;
            if (!enable_reg)
              begin
                word_ctr_rst             = 1;
                entropy_collect_ctrl_new = ENTROPY_IDLE;
                entropy_collect_ctrl_we  = 1;
              end
            else
              begin
                if (word_ctr_reg == 5'h1f)
                  begin
                    block_done               = 1;
                    entropy_collect_ctrl_new = ENTROPY_IDLE;
                    entropy_collect_ctrl_we  = 1;
                  end
                else
                  begin
                    word_ctr_inc             = 1;
                    entropy_collect_ctrl_new = ENTROPY_SRC2;
                    entropy_collect_ctrl_we  = 1;
                  end
              end
          end

        ENTROPY_SRC2:
          begin
            if (!enable_reg)
              begin
                word_ctr_rst             = 1;
                entropy_collect_ctrl_new = ENTROPY_IDLE;
                entropy_collect_ctrl_we  = 1;
              end
            else
              begin
                if (entropy2_enabled)
                  begin
                    if (entropy2_syn)
                      begin
                        muxed_entropy            = entropy2_data;
                        update_block             = 1;
                        entropy_collect_ctrl_new = ENTROPY_SRC2_ACK;
                        entropy_collect_ctrl_we  = 1;
                      end
                    else
                      if (entropy_timeout)
                        begin
                          entropy_timeout_ctr_rst  = 1;
                          entropy_collect_ctrl_new = ENTROPY_SRC0;
                          entropy_collect_ctrl_we  = 1;
                        end
                      else
                        begin
                          entropy_timeout_ctr_inc = 1;
                        end
                  end
                else
                  begin
                    entropy_collect_ctrl_new = ENTROPY_SRC0;
                    entropy_collect_ctrl_we  = 1;
                  end
              end
          end

        ENTROPY_SRC2_ACK:
          begin
            tmp_entropy2_ack = 1;
            if (!enable_reg)
              begin
                word_ctr_rst             = 1;
                entropy_collect_ctrl_new = ENTROPY_IDLE;
                entropy_collect_ctrl_we  = 1;
              end
            else
              begin
                if (word_ctr_reg == 5'h1f)
                  begin
                    block_done               = 1;
                    entropy_collect_ctrl_new = ENTROPY_IDLE;
                    entropy_collect_ctrl_we  = 1;
                  end
                else
                  begin
                    word_ctr_inc             = 1;
                    entropy_collect_ctrl_new = ENTROPY_SRC0;
                    entropy_collect_ctrl_we  = 1;
                  end
              end
          end

      endcase // case (entropy_collect_ctrl_reg)
    end // entropy_mux


  //----------------------------------------------------------------
  // entropy_timeout_logic
  //
  // Logic that updates the entropy timeout counter and signals
  // when the wait for antropy from a provider has exceeded
  // acceptable time.
  //----------------------------------------------------------------
  always @*
    begin : entropy_timeout_logic
      entropy_timeout_ctr_new = 24'h000000;
      entropy_timeout_ctr_we  = 0;
      entropy_timeout         = 0;

      if (entropy_timeout_ctr_reg == entropy_timeout_reg)
        begin
          entropy_timeout         = 1;
          entropy_timeout_ctr_new = 24'h000000;
          entropy_timeout_ctr_we  = 1;
        end

      if (entropy_timeout_ctr_rst)
        begin
          entropy_timeout_ctr_new = 24'h000000;
          entropy_timeout_ctr_we  = 1;
        end

      if (entropy_timeout_ctr_inc)
        begin
          entropy_timeout_ctr_new = entropy_timeout_ctr_reg + 1'b1;
          entropy_timeout_ctr_we  = 1;
        end
    end


  //----------------------------------------------------------------
  // word_ctr
  //----------------------------------------------------------------
  always @*
    begin : word_ctr
      word_ctr_new = 5'h00;
      word_ctr_we  = 0;

      if (word_ctr_rst)
        begin
          word_ctr_new = 5'h00;
          word_ctr_we  = 1;
        end

      if (word_ctr_inc)
        begin
          word_ctr_new = word_ctr_reg + 1'b1;
          word_ctr_we  = 1;
        end
    end // word_ctr


  //----------------------------------------------------------------
  // mixer_ctrl_fsm
  //
  // Control FSM for the mixer.
  //----------------------------------------------------------------
  always @*
    begin : mixer_ctrl_fsm
      seed_syn_new   = 0;
      seed_syn_we    = 0;
      init_done_new  = 0;
      init_done_we   = 0;
      hash_init      = 0;
      hash_next      = 0;
      collect_block  = 0;
      mixer_ctrl_new = CTRL_IDLE;
      mixer_ctrl_we  = 0;

      case (mixer_ctrl_reg)
        CTRL_IDLE:
          begin
            if (more_seed)
              begin
                collect_block  = 1;
                init_done_new  = 0;
                init_done_we   = 1;
                mixer_ctrl_new = CTRL_COLLECT;
                mixer_ctrl_we  = 1;
              end
          end

        CTRL_COLLECT:
          begin
            if ((discard))
              begin
                mixer_ctrl_new = CTRL_IDLE;
                mixer_ctrl_we  = 1;
              end
            else
              begin
                if (block_done)
                  begin
                    mixer_ctrl_new = CTRL_MIX;
                    mixer_ctrl_we  = 1;
                  end
              end
          end

        CTRL_MIX:
          begin
            if ((discard))
              begin
                mixer_ctrl_new = CTRL_IDLE;
                mixer_ctrl_we  = 1;
              end
            else
              begin
                if (init_done_reg)
                  begin
                    hash_next = 1;
                  end
                else
                  begin
                    hash_init = 1;
                  end
                mixer_ctrl_new = CTRL_SYN;
                mixer_ctrl_we  = 1;
              end
          end

        CTRL_SYN:
          begin
            if ((discard))
              begin
                mixer_ctrl_new = CTRL_IDLE;
                mixer_ctrl_we  = 1;
              end
            else if (hash_ready)
              begin
                seed_syn_new   = 1;
                seed_syn_we    = 1;
                mixer_ctrl_new = CTRL_ACK;
                mixer_ctrl_we  = 1;
              end

          end

        CTRL_ACK:
          begin
            if ((discard))
              begin
                mixer_ctrl_new = CTRL_IDLE;
                mixer_ctrl_we  = 1;
              end
            else if (seed_ack)
              begin
                seed_syn_new   = 0;
                seed_syn_we    = 1;
                mixer_ctrl_new = CTRL_NEXT;
                mixer_ctrl_we  = 1;
              end
          end

        CTRL_NEXT:
          begin
            if ((discard))
              begin
                mixer_ctrl_new = CTRL_IDLE;
                mixer_ctrl_we  = 1;
              end
            else if (more_seed)
              begin
                collect_block  = 1;
                init_done_new  = 1;
                init_done_we   = 1;
                mixer_ctrl_new = CTRL_COLLECT;
                mixer_ctrl_we  = 1;
              end
          end

      endcase // case (cspng_ctrl_reg)
    end // mixer_ctrl_fsm

endmodule // trng_mixer

//======================================================================
// EOF trng_mixer.v
//======================================================================