data/full_repos/permissive/466022941/verilog/rtl/sha256.v
data/verilator_xmls/ddede04e-c31c-4cef-b719-1815c5f19962.xml
module sha256(

              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
             );




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

  localparam ADDR_CTRL        = 8'h08;
  localparam CTRL_INIT_BIT    = 0;
  localparam CTRL_NEXT_BIT    = 1;
  localparam CTRL_MODE_BIT    = 2;

  localparam ADDR_STATUS      = 8'h09;
  localparam STATUS_READY_BIT = 0;
  localparam STATUS_VALID_BIT = 1;

  localparam ADDR_BLOCK0    = 8'h10;
  localparam ADDR_BLOCK15   = 8'h1f;

  localparam ADDR_DIGEST0   = 8'h20;
  localparam ADDR_DIGEST7   = 8'h27;

  localparam CORE_NAME0     = 32'h73686132;
  localparam CORE_NAME1     = 32'h2d323536;
  localparam CORE_VERSION   = 32'h312e3830;

  localparam MODE_SHA_224   = 1'h0;
  localparam MODE_SHA_256   = 1'h1;





  reg init_reg;
  reg init_new;

  reg next_reg;
  reg next_new;

  reg mode_reg;
  reg mode_new;
  reg mode_we;

  reg ready_reg;

  reg [31 : 0] block_reg [0 : 15];
  reg          block_we;

  reg [255 : 0] digest_reg;

  reg digest_valid_reg;






  wire [511 : 0] core_block;




  wire [31:0] added_data [7:0];


  reg [31 : 0]   tmp_read_data;
  reg            tmp_error;





  assign core_block = {block_reg[00], block_reg[01], block_reg[02], block_reg[03],
                       block_reg[04], block_reg[05], block_reg[06], block_reg[07],
                       block_reg[08], block_reg[09], block_reg[10], block_reg[11],
                       block_reg[12], block_reg[13], block_reg[14], block_reg[15]};

  assign read_data = tmp_read_data;
  assign error     = tmp_error;

  assign added_data[0] = block_reg[00] + block_reg[01];
  assign added_data[1] = block_reg[02] + block_reg[03];
  assign added_data[2] = block_reg[04] + block_reg[05];
  assign added_data[3] = block_reg[06] + block_reg[07];
  assign added_data[4] = block_reg[08] + block_reg[09];
  assign added_data[5] = block_reg[10] + block_reg[11];
  assign added_data[6] = block_reg[12] + block_reg[13];
  assign added_data[7] = block_reg[14] + block_reg[15];


































  always @ (posedge clk or negedge reset_n)
    begin : reg_update
      integer i;

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

          init_reg         <= 0;
          next_reg         <= 0;
          ready_reg        <= 0;
          mode_reg         <= MODE_SHA_256;
          digest_reg       <= 256'h0;
          digest_valid_reg <= 0;
        end
      else
        begin


          ready_reg        <= 1'b1;

          init_reg         <= init_new;
          next_reg         <= next_new;

          if (mode_we)
            mode_reg <= mode_new;





          if (digest_valid_reg)
            digest_reg <= {added_data[0], added_data[1], added_data[2], added_data[3], added_data[4], added_data[5], added_data[6], added_data[7]};

          if (block_we) begin
            block_reg[address[3 : 0]] <= write_data;
            digest_valid_reg <= 1'b0;
          end
          else begin
            digest_valid_reg <= 1'b1;
          end
        end
    end








  always @*
    begin : api_logic
      init_new      = 0;
      next_new      = 0;
      mode_new      = 0;
      mode_we       = 0;
      block_we      = 0;
      tmp_read_data = 32'h0;
      tmp_error     = 0;

      if (cs)
        begin
          if (we)
            begin
              if (address == ADDR_CTRL)
                begin
                  init_new = write_data[CTRL_INIT_BIT];
                  next_new = write_data[CTRL_NEXT_BIT];
                  mode_new = write_data[CTRL_MODE_BIT];
                  mode_we  = 1;
                end

              if ((address >= ADDR_BLOCK0) && (address <= ADDR_BLOCK15))
                block_we = 1;
            end

          else
            begin

              if ((address >= ADDR_BLOCK0) && (address <= ADDR_BLOCK15))
                tmp_read_data = block_reg[address[3 : 0]];

              if ((address >= ADDR_DIGEST0) && (address <= ADDR_DIGEST7))
                tmp_read_data = digest_reg[(7 - (address - ADDR_DIGEST0)) * 32 +: 32];

              case (address)

                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 = {29'h0, mode_reg, next_reg, init_reg};

                ADDR_STATUS:
                  tmp_read_data = {30'h0, digest_valid_reg, ready_reg};

                default:
                  begin
                  end
              endcase
            end
        end
    end
endmodule
module sha256(

              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
             );





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

  localparam ADDR_CTRL        = 8'h08;
  localparam CTRL_INIT_BIT    = 0;
  localparam CTRL_NEXT_BIT    = 1;
  localparam CTRL_MODE_BIT    = 2;

  localparam ADDR_STATUS      = 8'h09;
  localparam STATUS_READY_BIT = 0;
  localparam STATUS_VALID_BIT = 1;

  localparam ADDR_BLOCK0    = 8'h10;
  localparam ADDR_BLOCK15   = 8'h1f;

  localparam ADDR_DIGEST0   = 8'h20;
  localparam ADDR_DIGEST7   = 8'h27;

  localparam CORE_NAME0     = 32'h73686132;
  localparam CORE_NAME1     = 32'h2d323536;
  localparam CORE_VERSION   = 32'h312e3830;

  localparam MODE_SHA_224   = 1'h0;
  localparam MODE_SHA_256   = 1'h1;





  reg init_reg;
  reg init_new;

  reg next_reg;
  reg next_new;

  reg mode_reg;
  reg mode_new;
  reg mode_we;

  reg ready_reg;

  reg [31 : 0] block_reg [0 : 15];
  reg          block_we;

  reg [255 : 0] digest_reg;

  reg digest_valid_reg;






  wire [511 : 0] core_block;




  wire [31:0] added_data [7:0];


  reg [31 : 0]   tmp_read_data;
  reg            tmp_error;





  assign core_block = {block_reg[00], block_reg[01], block_reg[02], block_reg[03],
                       block_reg[04], block_reg[05], block_reg[06], block_reg[07],
                       block_reg[08], block_reg[09], block_reg[10], block_reg[11],
                       block_reg[12], block_reg[13], block_reg[14], block_reg[15]};

  assign read_data = tmp_read_data;
  assign error     = tmp_error;

  assign added_data[0] = block_reg[00] + block_reg[01];
  assign added_data[1] = block_reg[02] + block_reg[03];
  assign added_data[2] = block_reg[04] + block_reg[05];
  assign added_data[3] = block_reg[06] + block_reg[07];
  assign added_data[4] = block_reg[08] + block_reg[09];
  assign added_data[5] = block_reg[10] + block_reg[11];
  assign added_data[6] = block_reg[12] + block_reg[13];
  assign added_data[7] = block_reg[14] + block_reg[15];


































  always @ (posedge clk or negedge reset_n)
    begin : reg_update
      integer i;

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

          init_reg         <= 0;
          next_reg         <= 0;
          ready_reg        <= 0;
          mode_reg         <= MODE_SHA_256;
          digest_reg       <= 256'h0;
          digest_valid_reg <= 0;
        end
      else
        begin


          ready_reg        <= 1'b1;

          init_reg         <= init_new;
          next_reg         <= next_new;

          if (mode_we)
            mode_reg <= mode_new;





          if (digest_valid_reg)
            digest_reg <= {added_data[0], added_data[1], added_data[2], added_data[3], added_data[4], added_data[5], added_data[6], added_data[7]};

          if (block_we) begin
            block_reg[address[3 : 0]] <= write_data;
            digest_valid_reg <= 1'b0;
          end
          else begin
            digest_valid_reg <= 1'b1;
          end
        end
    end








  always @*
    begin : api_logic
      init_new      = 0;
      next_new      = 0;
      mode_new      = 0;
      mode_we       = 0;
      block_we      = 0;
      tmp_read_data = 32'h0;
      tmp_error     = 0;

      if (cs)
        begin
          if (we)
            begin
              if (address == ADDR_CTRL)
                begin
                  init_new = write_data[CTRL_INIT_BIT];
                  next_new = write_data[CTRL_NEXT_BIT];
                  mode_new = write_data[CTRL_MODE_BIT];
                  mode_we  = 1;
                end

              if ((address >= ADDR_BLOCK0) && (address <= ADDR_BLOCK15))
                block_we = 1;
            end

          else
            begin

              if ((address >= ADDR_BLOCK0) && (address <= ADDR_BLOCK15))
                tmp_read_data = block_reg[address[3 : 0]];

              if ((address >= ADDR_DIGEST0) && (address <= ADDR_DIGEST7))
                tmp_read_data = digest_reg[(7 - (address - ADDR_DIGEST0)) * 32 +: 32];

              case (address)

                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 = {29'h0, mode_reg, next_reg, init_reg};

                ADDR_STATUS:
                  tmp_read_data = {30'h0, digest_valid_reg, ready_reg};

                default:
                  begin
                  end
              endcase
            end
        end
    end
endmodule