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







                                                                        
                                   
                       
  
























                                                                           







                                                                        




                                                   

                                              
                                                
                                                  


                                                       
                                                  
                                                 

                                                 

                                                    





                                                                    



                                           
                                           

                                       
 
                                           
                                       
 

                                           
                                           
 
                                           
 


                                           
 
















                                           
                                                      
                                                      
 









                                
 
                                        
                                                       
 



                                                    


























                                                                    

                                   
                                  
 




                                    









                              






















                                    
                              
 



                                                                    

                           




                                       
                              
 

                                


                          

                                        

                               



                                                                    
                                        


                                        
                                          
                            
                                                 




                                                                    


                                            
 

                                             
 




                                                    
 

                                                     
 


                                                                

 


                                               
 



                                                                        
 



                                                    












                                                                    




                                                    
                                                   
                                              


                                   
                                   




                                                             




                                         


                                    
                                     

                            
                                             

                           
                                           

                            
                                             

                              
                                                 

                           

                                                  



                                

                                                       
 


                                                       
                       
                                   
 
                             
                                               
 
                            
                                             

                                
                                                     

                                 
                                                       




                                                                    

















                                                                    
                                         





















                                                             
                                    




                                                    
                                     
















                                                     
                           
                                               

                           
                                               

                             
                                                 
 
                          
                                                                         

                            
                                                                       





                                                                
 


                                                        

                              
                                             
                                      


                                
                                                                  
 
                                    
                                                       
 
                                     
                                                        











                                                                    





                                                            
    



                                                              


                                                                    



                                             
                               


                        

                                            



                        
                                                    
                                 

                                                         

           

                                                                         
             
                               




                                                                    




















                                                                    



















                                                                    



                                 
                                 





                                         
                                       













                                              
                                                     





                                              


                                             






                                             
                                                     






                                              






                                              
                                                     























                                                       
                                                     





                                              




                                                 




                   
                                                     












                                              
                                                     












                                              
                                                     



                                              
                                                           








                                                   
                                                     































                                                  



                                         



                







                                                                        
//======================================================================
//
// trng_csprng.v
// -------------
// CSPRNG 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_csprng(
                   // Clock and reset.
                   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          more_seed,
                   output wire          security_error,

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

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


  //----------------------------------------------------------------
  // Internal constant and parameter definitions.
  //----------------------------------------------------------------
  localparam ADDR_NAME0            = 8'h00;
  localparam ADDR_NAME1            = 8'h01;
  localparam ADDR_VERSION          = 8'h02;

  localparam ADDR_CTRL             = 8'h08;
  localparam CTRL_ENABLE_BIT       = 0;
  localparam CTRL_SEED_BIT         = 1;

  localparam ADDR_STATUS           = 8'h09;
  localparam STATUS_RND_VALID_BIT  = 1;

  localparam ADDR_STAT_BLOCKS_LOW  = 8'h14;
  localparam ADDR_STAT_BLOCKS_HIGH = 8'h15;
  localparam ADDR_STAT_RESEEDS     = 8'h16;

  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'h0000000100000000;

  localparam CTRL_IDLE   = 4'h0;
  localparam CTRL_SEED0  = 4'h1;
  localparam CTRL_NSYN   = 4'h2;
  localparam CTRL_SEED1  = 4'h3;
  localparam CTRL_INIT0  = 4'h4;
  localparam CTRL_INIT1  = 4'h5;
  localparam CTRL_NEXT0  = 4'h6;
  localparam CTRL_NEXT1  = 4'h7;
  localparam CTRL_MORE   = 4'h8;
  localparam CTRL_CANCEL = 4'hf;

  localparam DEFAULT_NUM_ROUNDS = 5'h18;
  localparam DEFAULT_NUM_BLOCKS = 64'h0000000001000000;

  parameter CORE_NAME0     = 32'h63737072; // "cspr"
  parameter CORE_NAME1     = 32'h6e672020; // "ng  "
  parameter CORE_VERSION   = 32'h302e3530; // "0.50"


  //----------------------------------------------------------------
  // Registers including update variables and write enable.
  //----------------------------------------------------------------
  reg [255 : 0] cipher_key_reg;
  reg [255 : 0] cipher_key_new;
  reg           cipher_key_we;

  reg [63 : 0]  cipher_iv_reg;
  reg [63 : 0]  cipher_iv_new;
  reg           cipher_iv_we;

  reg [63 : 0]  cipher_ctr_reg;
  reg [63 : 0]  cipher_ctr_new;
  reg           cipher_ctr_we;

  reg [511 : 0] cipher_block_reg;
  reg [511 : 0] cipher_block_new;
  reg           cipher_block_we;

  reg [63 : 0]  block_ctr_reg;
  reg [63 : 0]  block_ctr_new;
  reg           block_ctr_inc;
  reg           block_ctr_rst;
  reg           block_ctr_we;
  reg           block_ctr_max;

  reg [63 : 0]  block_stat_ctr_reg;
  reg [63 : 0]  block_stat_ctr_new;
  reg           block_stat_ctr_we;

  reg [31 : 0]  reseed_stat_ctr_reg;
  reg [31 : 0]  reseed_stat_ctr_new;
  reg           reseed_stat_ctr_inc;
  reg           reseed_stat_ctr_we;

  reg           ready_reg;
  reg           ready_new;
  reg           ready_we;

  reg           more_seed_reg;
  reg           more_seed_new;

  reg           seed_ack_reg;
  reg           seed_ack_new;

  reg           enable_reg;
  reg           enable_new;
  reg           enable_we;

  reg           seed_reg;
  reg           seed_new;

  reg [4 : 0]   num_rounds_reg;
  reg [4 : 0]   num_rounds_new;
  reg           num_rounds_we;

  reg [31 : 0]  num_blocks_low_reg;
  reg [31 : 0]  num_blocks_low_new;
  reg           num_blocks_low_we;

  reg [31 : 0]  num_blocks_high_reg;
  reg [31 : 0]  num_blocks_high_new;
  reg           num_blocks_high_we;

  reg [3 : 0]   csprng_ctrl_reg;
  reg [3 : 0]   csprng_ctrl_new;
  reg           csprng_ctrl_we;

  reg [31 : 0]  tmp_read_data;


  //----------------------------------------------------------------
  // Wires.
  //----------------------------------------------------------------
  reg            tmp_error;

  reg            cipher_init;
  reg            cipher_next;

  wire [511 : 0] cipher_data_out;
  wire           cipher_data_out_valid;
  wire           cipher_ready;

  wire           fifo_more_data;
  reg            fifo_discard;
  wire           rnd_syn;
  wire [31 : 0]  rnd_data;
  reg            rnd_ack;
  reg            fifo_cipher_data_valid;

  wire           muxed_rnd_ack;


  //----------------------------------------------------------------
  // Concurrent connectivity for ports etc.
  //----------------------------------------------------------------
  assign read_data      = tmp_read_data;
  assign error          = tmp_error;
  assign seed_ack       = seed_ack_reg;
  assign more_seed      = more_seed_reg;
  assign debug          = rnd_data[7 : 0];
  assign security_error = 0;
  assign muxed_rnd_ack  = rnd_ack | debug_update;


  //----------------------------------------------------------------
  // core instantiation.
  //----------------------------------------------------------------
  chacha_core cipher_inst(
                          .clk(clk),
                          .reset_n(reset_n),

                          .init(cipher_init),
                          .next(cipher_next),

                          .key(cipher_key_reg),
                          .keylen(CIPHER_KEYLEN256),
                          .iv(cipher_iv_reg),
                          .ctr(cipher_ctr_reg),
                          .rounds(num_rounds_reg),

                          .data_in(cipher_block_reg),
                          .ready(cipher_ready),

                          .data_out(cipher_data_out),
                          .data_out_valid(cipher_data_out_valid)
                         );


  trng_csprng_fifo fifo_inst(
                             .clk(clk),
                             .reset_n(reset_n),

                             .csprng_data(cipher_data_out),
                             .csprng_data_valid(fifo_cipher_data_valid),
                             .discard(fifo_discard),
                             .more_data(fifo_more_data),

                             .rnd_syn(rnd_syn),
                             .rnd_data(rnd_data),
                             .rnd_ack(muxed_rnd_ack)
                            );


  //----------------------------------------------------------------
  // reg_update
  //
  // Update functionality for all registers in the core.
  // All registers are positive edge triggered with synchronous
  // active low reset. All registers have write enable.
  //----------------------------------------------------------------
  always @ (posedge clk or negedge reset_n)
    begin
      if (!reset_n)
        begin
          cipher_key_reg      <= {8{32'h00000000}};
          cipher_iv_reg       <= {2{32'h00000000}};
          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}};
          reseed_stat_ctr_reg <= 32'h00000000;
          more_seed_reg       <= 0;
          seed_ack_reg        <= 0;
          ready_reg           <= 0;
          enable_reg          <= 1;
          seed_reg            <= 0;
          num_rounds_reg      <= DEFAULT_NUM_ROUNDS;
          num_blocks_low_reg  <= DEFAULT_NUM_BLOCKS[31 : 0];
          num_blocks_high_reg <= DEFAULT_NUM_BLOCKS[63 : 32];
          csprng_ctrl_reg     <= CTRL_IDLE;
        end
      else
        begin
          more_seed_reg <= more_seed_new;
          seed_ack_reg  <= seed_ack_new;
          seed_reg      <= seed_new;

          if (enable_we)
            enable_reg <= enable_new;

          if (cipher_key_we)
            cipher_key_reg <= cipher_key_new;

          if (cipher_iv_we)
            cipher_iv_reg <= cipher_iv_new;

          if (cipher_ctr_we)
            cipher_ctr_reg <= cipher_ctr_new;

          if (cipher_block_we)
            cipher_block_reg <= cipher_block_new;

          if (block_ctr_we)
            begin
              block_ctr_reg      <= block_ctr_new;
            end

          if (block_stat_ctr_we)
            begin
              block_stat_ctr_reg <= block_stat_ctr_new;
            end

          if (reseed_stat_ctr_we)
            reseed_stat_ctr_reg <= reseed_stat_ctr_new;

          if (ready_we)
            ready_reg <= ready_new;

          if (csprng_ctrl_we)
            csprng_ctrl_reg <= csprng_ctrl_new;

          if (num_rounds_we)
            num_rounds_reg <= num_rounds_new;

          if (num_blocks_low_we)
            num_blocks_low_reg <= num_blocks_low_new;

          if (num_blocks_high_we)
            num_blocks_high_reg <= num_blocks_high_new;
        end
    end // reg_update


  //----------------------------------------------------------------
  // csprng_api_logic
  //----------------------------------------------------------------
  always @*
    begin : csprng_api_logic
      enable_new          = 0;
      enable_we           = 0;
      seed_new            = 0;

      num_rounds_new      = 5'h00;
      num_rounds_we       = 0;

      num_blocks_low_new  = 32'h00000000;
      num_blocks_low_we   = 0;
      num_blocks_high_new = 32'h00000000;
      num_blocks_high_we  = 0;

      rnd_ack             = 0;

      tmp_read_data       = 32'h00000000;
      tmp_error           = 0;

      if (cs)
        begin
          if (we)
            begin
              // Write operations.
              case (address)
                // Write operations.
                ADDR_CTRL:
                  begin
                    enable_new = write_data[CTRL_ENABLE_BIT];
                    enable_we  = 1;
                    seed_new   = write_data[CTRL_SEED_BIT];
                  end

                ADDR_NUM_ROUNDS:
                  begin
                    num_rounds_new = write_data[4 : 0];
                    num_rounds_we  = 1;
                  end

                ADDR_NUM_BLOCKS_LOW:
                  begin
                    num_blocks_low_new = write_data;
                    num_blocks_low_we  = 1;
                  end

                ADDR_NUM_BLOCKS_HIGH:
                  begin
                    num_blocks_high_new = write_data;
                    num_blocks_high_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_CTRL:
                    tmp_read_data = {30'h00000000, seed_reg, enable_reg};

                ADDR_STATUS:
                    tmp_read_data = {30'h00000000, rnd_syn, ready_reg};

                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_STAT_RESEEDS:
                    tmp_read_data = reseed_stat_ctr_reg;

                ADDR_RND_DATA:
                  begin
                    tmp_read_data = rnd_data;
                    rnd_ack       = 1;
                  end

                ADDR_NUM_ROUNDS:
                    tmp_read_data = {27'h0000000, num_rounds_reg};

                ADDR_NUM_BLOCKS_LOW:
                    tmp_read_data = num_blocks_low_reg;

                ADDR_NUM_BLOCKS_HIGH:
                    tmp_read_data = num_blocks_high_reg;

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


  //----------------------------------------------------------------
  // block_ctr
  //
  // Logic to implement the block counter. This includes the
  // 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      = {2{32'h00000000}};
      block_ctr_we       = 1'b0;
      block_ctr_max      = 1'b0;
      block_stat_ctr_new = {2{32'h00000000}};
      block_stat_ctr_we = 1'b0;

      if (block_ctr_rst)
        begin
          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_stat_ctr_new = block_stat_ctr_reg + 1'b1;
          block_stat_ctr_we  = 1;
        end

      if ((block_ctr_reg == {num_blocks_high_reg, num_blocks_low_reg}) ||
          (block_ctr_reg == CIPHER_MAX_BLOCKS))
        begin
          block_ctr_max = 1'b1;
        end
    end // block_ctr


  //----------------------------------------------------------------
  // reseed_ctr
  //
  // A simple monotonically increasing counter that counts the
  // number of times the CSPRNG has been reseeded. is reseeded.
  // Note that the counter is 32-bit and it is up to SW to handle
  // wrap around issues.
  //----------------------------------------------------------------
  always @*
    begin : reseed_ctr
      reseed_stat_ctr_new = 32'h00000000;
      reseed_stat_ctr_we  = 0;

      if (reseed_stat_ctr_inc)
        begin
          reseed_stat_ctr_new = reseed_stat_ctr_reg + 1'b1;
          reseed_stat_ctr_we  = 1;
        end
    end // reseed_ctr


  //----------------------------------------------------------------
  // csprng_ctrl_fsm
  //
  // Control FSM for the CSPRNG.
  //----------------------------------------------------------------
  always @*
    begin : csprng_ctrl_fsm
      cipher_key_new         = {8{32'h00000000}};
      cipher_key_we          = 0;
      cipher_iv_new          = {2{32'h00000000}};
      cipher_iv_we           = 0;
      cipher_ctr_new         = {2{32'h00000000}};
      cipher_ctr_we          = 0;
      cipher_block_new       = {16{32'h00000000}};
      cipher_block_we        = 0;
      cipher_init            = 0;
      cipher_next            = 0;
      block_ctr_rst          = 0;
      block_ctr_inc          = 0;
      ready_new              = 0;
      ready_we               = 0;
      seed_ack_new           = 0;
      more_seed_new          = 0;
      fifo_discard           = 0;
      fifo_cipher_data_valid = 0;
      reseed_stat_ctr_inc    = 0;
      csprng_ctrl_new        = CTRL_IDLE;
      csprng_ctrl_we         = 0;

      case (csprng_ctrl_reg)
        CTRL_IDLE:
          begin
            if (!enable_reg || discard)
              begin
                csprng_ctrl_new = CTRL_CANCEL;
                csprng_ctrl_we  = 1;
              end
            else if (fifo_more_data)
              begin
                more_seed_new   = 1;
                csprng_ctrl_new = CTRL_SEED0;
                csprng_ctrl_we  = 1;
              end
          end

        CTRL_SEED0:
          begin
            if ((!enable_reg) || seed_reg || discard)
              begin
                csprng_ctrl_new = CTRL_CANCEL;
                csprng_ctrl_we  = 1;
              end
            else if (seed_syn)
              begin
                seed_ack_new     = 1;
                cipher_block_new = seed_data;
                cipher_block_we  = 1;
                csprng_ctrl_new  = CTRL_NSYN;
                csprng_ctrl_we   = 1;
              end
          end

        CTRL_NSYN:
          begin
            if ((!enable_reg) || seed_reg || discard)
              begin
                csprng_ctrl_new = CTRL_CANCEL;
                csprng_ctrl_we  = 1;
              end
            else
              begin
                more_seed_new    = 1;
                csprng_ctrl_new  = CTRL_SEED1;
                csprng_ctrl_we   = 1;
              end
          end

        CTRL_SEED1:
          begin
            if ((!enable_reg) || seed_reg || discard)
              begin
                csprng_ctrl_new = CTRL_CANCEL;
                csprng_ctrl_we  = 1;
              end
            else if (seed_syn)
              begin
                seed_ack_new    = 1;
                cipher_key_new  = seed_data[255 : 0];
                cipher_key_we   = 1;
                cipher_iv_new   = seed_data[319 : 256];
                cipher_iv_we    = 1;
                cipher_ctr_new  = seed_data[383 : 320];
                cipher_ctr_we   = 1;
                csprng_ctrl_new = CTRL_INIT0;
                csprng_ctrl_we  = 1;
              end
            else
              begin
                more_seed_new = 1;
              end
          end

        CTRL_INIT0:
          begin
            if ((!enable_reg) || seed_reg || discard)
              begin
                csprng_ctrl_new = CTRL_CANCEL;
                csprng_ctrl_we  = 1;
              end
            else
              begin
                reseed_stat_ctr_inc = 1;
                cipher_init         = 1;
                block_ctr_rst       = 1;
                csprng_ctrl_new     = CTRL_INIT1;
                csprng_ctrl_we      = 1;
              end
          end

        CTRL_INIT1:
          begin
            if ((!enable_reg) || seed_reg || discard)
              begin
                csprng_ctrl_new = CTRL_CANCEL;
                csprng_ctrl_we  = 1;
              end
            else if (cipher_ready)
              begin
                csprng_ctrl_new = CTRL_NEXT0;
                csprng_ctrl_we  = 1;
              end
          end

        CTRL_NEXT0:
          begin
            if ((!enable_reg) || seed_reg || discard)
              begin
                csprng_ctrl_new = CTRL_CANCEL;
                csprng_ctrl_we  = 1;
              end
            else
              begin
                cipher_next     = 1;
                csprng_ctrl_new = CTRL_NEXT1;
                csprng_ctrl_we  = 1;
              end
          end

        CTRL_NEXT1:
            if ((!enable_reg) || seed_reg || discard)
              begin
                csprng_ctrl_new = CTRL_CANCEL;
                csprng_ctrl_we  = 1;
              end
            else if (cipher_ready && cipher_data_out_valid)
              begin
                block_ctr_inc          = 1;
                fifo_cipher_data_valid = 1;
                csprng_ctrl_new        = CTRL_MORE;
                csprng_ctrl_we         = 1;
              end

        CTRL_MORE:
          begin
            if ((!enable_reg) || seed_reg || discard)
              begin
                csprng_ctrl_new = CTRL_CANCEL;
                csprng_ctrl_we  = 1;
              end
            else if (fifo_more_data)
              begin
                if (block_ctr_max)
                  begin
                    more_seed_new   = 1;
                    csprng_ctrl_new = CTRL_SEED0;
                    csprng_ctrl_we  = 1;
                  end
                else
                  begin
                    csprng_ctrl_new = CTRL_NEXT0;
                    csprng_ctrl_we  = 1;
                  end
              end
          end

        CTRL_CANCEL:
          begin
            fifo_discard     = 1;
            cipher_key_new   = {8{32'h00000000}};
            cipher_key_we    = 1;
            cipher_iv_new    = {2{32'h00000000}};
            cipher_iv_we     = 1;
            cipher_ctr_new   = {2{32'h00000000}};
            cipher_ctr_we    = 1;
            cipher_block_new = {16{32'h00000000}};
            cipher_block_we  = 1;
            block_ctr_rst    = 1;
            csprng_ctrl_new  = CTRL_IDLE;
            csprng_ctrl_we   = 1;
          end

        default:
          begin
          end

      endcase // case (cspng_ctrl_reg)
    end // csprng_ctrl_fsm

endmodule // trng_csprng

//======================================================================
// EOF trng_csprng.v
//======================================================================