data/full_repos/permissive/194918293/src/rtl/aes_siv_core.v
 line:189: before: "("
1: b'%Error: data/full_repos/permissive/194918293/src/rtl/aes_siv_core.v:203: Cannot find file containing module: \'aes_core\'\n  aes_core aes(\n  ^~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/194918293/src/rtl,data/full_repos/permissive/194918293/aes_core\n             data/full_repos/permissive/194918293/src/rtl,data/full_repos/permissive/194918293/aes_core.v\n             data/full_repos/permissive/194918293/src/rtl,data/full_repos/permissive/194918293/aes_core.sv\n             aes_core\n             aes_core.v\n             aes_core.sv\n             obj_dir/aes_core\n             obj_dir/aes_core.v\n             obj_dir/aes_core.sv\n%Error: data/full_repos/permissive/194918293/src/rtl/aes_siv_core.v:221: Cannot find file containing module: \'cmac_core\'\n  cmac_core cmac(\n  ^~~~~~~~~\n%Warning-WIDTH: data/full_repos/permissive/194918293/src/rtl/aes_siv_core.v:255: Operator ASSIGNDLY expects 4 bits on the Assign RHS, but Assign RHS\'s VARREF \'CTRL_IDLE\' generates 5 bits.\n                                                                               : ... In instance aes_siv_core\n          core_ctrl_reg  <= CTRL_IDLE;\n                         ^~\n                ... Use "/* verilator lint_off WIDTH */" and lint_on around source to disable this message.\n%Warning-WIDTH: data/full_repos/permissive/194918293/src/rtl/aes_siv_core.v:386: Operator ASSIGN expects 4 bits on the Assign RHS, but Assign RHS\'s VARREF \'CTRL_IDLE\' generates 5 bits.\n                                                                               : ... In instance aes_siv_core\n      core_ctrl_new   = CTRL_IDLE;\n                      ^\n%Warning-WIDTH: data/full_repos/permissive/194918293/src/rtl/aes_siv_core.v:404: Operator ASSIGN expects 4 bits on the Assign RHS, but Assign RHS\'s VARREF \'CTRL_S2V_INIT1\' generates 5 bits.\n                                                                               : ... In instance aes_siv_core\n                core_ctrl_new   = CTRL_S2V_INIT1;\n                                ^\n%Warning-WIDTH: data/full_repos/permissive/194918293/src/rtl/aes_siv_core.v:422: Operator ASSIGN expects 4 bits on the Assign RHS, but Assign RHS\'s VARREF \'CTRL_IDLE\' generates 5 bits.\n                                                                               : ... In instance aes_siv_core\n                core_ctrl_new = CTRL_IDLE;\n                              ^\n%Warning-WIDTH: data/full_repos/permissive/194918293/src/rtl/aes_siv_core.v:434: Operator ASSIGN expects 4 bits on the Assign RHS, but Assign RHS\'s VARREF \'CTRL_S2V_FIRST1\' generates 5 bits.\n                                                                               : ... In instance aes_siv_core\n                core_ctrl_new = CTRL_S2V_FIRST1;\n                              ^\n%Warning-WIDTH: data/full_repos/permissive/194918293/src/rtl/aes_siv_core.v:447: Operator ASSIGN expects 4 bits on the Assign RHS, but Assign RHS\'s VARREF \'CTRL_IDLE\' generates 5 bits.\n                                                                               : ... In instance aes_siv_core\n                core_ctrl_new = CTRL_IDLE;\n                              ^\n%Warning-WIDTH: data/full_repos/permissive/194918293/src/rtl/aes_siv_core.v:457: Operator ASSIGN expects 4 bits on the Assign RHS, but Assign RHS\'s VARREF \'CTRL_S2V_NEXT1\' generates 5 bits.\n                                                                               : ... In instance aes_siv_core\n            core_ctrl_new = CTRL_S2V_NEXT1;\n                          ^\n%Warning-WIDTH: data/full_repos/permissive/194918293/src/rtl/aes_siv_core.v:469: Operator ASSIGN expects 4 bits on the Assign RHS, but Assign RHS\'s VARREF \'CTRL_IDLE\' generates 5 bits.\n                                                                               : ... In instance aes_siv_core\n                core_ctrl_new = CTRL_IDLE;\n                              ^\n%Warning-WIDTH: data/full_repos/permissive/194918293/src/rtl/aes_siv_core.v:482: Operator ASSIGN expects 4 bits on the Assign RHS, but Assign RHS\'s VARREF \'CTRL_S2V_FINAL1\' generates 5 bits.\n                                                                               : ... In instance aes_siv_core\n            core_ctrl_new   = CTRL_S2V_FINAL1;\n                            ^\n%Warning-WIDTH: data/full_repos/permissive/194918293/src/rtl/aes_siv_core.v:497: Operator ASSIGN expects 4 bits on the Assign RHS, but Assign RHS\'s VARREF \'CTRL_IDLE\' generates 5 bits.\n                                                                               : ... In instance aes_siv_core\n                core_ctrl_new = CTRL_IDLE;\n                              ^\n%Warning-WIDTH: data/full_repos/permissive/194918293/src/rtl/aes_siv_core.v:509: Operator ASSIGN expects 4 bits on the Assign RHS, but Assign RHS\'s VARREF \'CTRL_S2V_FINALIZE1\' generates 5 bits.\n                                                                               : ... In instance aes_siv_core\n                core_ctrl_new   = CTRL_S2V_FINALIZE1;\n                                ^\n%Warning-WIDTH: data/full_repos/permissive/194918293/src/rtl/aes_siv_core.v:514: Operator ASSIGN expects 4 bits on the Assign RHS, but Assign RHS\'s VARREF \'CTRL_S2V_FINALIZE3\' generates 5 bits.\n                                                                               : ... In instance aes_siv_core\n                core_ctrl_new = CTRL_S2V_FINALIZE3;\n                              ^\n%Warning-WIDTH: data/full_repos/permissive/194918293/src/rtl/aes_siv_core.v:528: Operator ASSIGN expects 4 bits on the Assign RHS, but Assign RHS\'s VARREF \'CTRL_S2V_FINALIZE2\' generates 5 bits.\n                                                                               : ... In instance aes_siv_core\n                core_ctrl_new   = CTRL_S2V_FINALIZE2;\n                                ^\n%Warning-WIDTH: data/full_repos/permissive/194918293/src/rtl/aes_siv_core.v:544: Operator ASSIGN expects 4 bits on the Assign RHS, but Assign RHS\'s VARREF \'CTRL_IDLE\' generates 5 bits.\n                                                                               : ... In instance aes_siv_core\n                core_ctrl_new = CTRL_IDLE;\n                              ^\n%Warning-WIDTH: data/full_repos/permissive/194918293/src/rtl/aes_siv_core.v:555: Operator ASSIGN expects 4 bits on the Assign RHS, but Assign RHS\'s VARREF \'CTRL_IDLE\' generates 5 bits.\n                                                                               : ... In instance aes_siv_core\n            core_ctrl_new = CTRL_IDLE;\n                          ^\n%Warning-WIDTH: data/full_repos/permissive/194918293/src/rtl/aes_siv_core.v:563: Operator ASSIGN expects 4 bits on the Assign RHS, but Assign RHS\'s VARREF \'CTRL_CTR_INIT1\' generates 5 bits.\n                                                                               : ... In instance aes_siv_core\n            core_ctrl_new = CTRL_CTR_INIT1;\n                          ^\n%Warning-WIDTH: data/full_repos/permissive/194918293/src/rtl/aes_siv_core.v:574: Operator ASSIGN expects 4 bits on the Assign RHS, but Assign RHS\'s VARREF \'CTRL_IDLE\' generates 5 bits.\n                                                                               : ... In instance aes_siv_core\n                core_ctrl_new = CTRL_IDLE;\n                              ^\n%Warning-WIDTH: data/full_repos/permissive/194918293/src/rtl/aes_siv_core.v:582: Operator ASSIGN expects 4 bits on the Assign RHS, but Assign RHS\'s VARREF \'CTRL_CTR_NEXT1\' generates 5 bits.\n                                                                               : ... In instance aes_siv_core\n            core_ctrl_new = CTRL_CTR_NEXT1;\n                          ^\n%Warning-WIDTH: data/full_repos/permissive/194918293/src/rtl/aes_siv_core.v:595: Operator ASSIGN expects 4 bits on the Assign RHS, but Assign RHS\'s VARREF \'CTRL_IDLE\' generates 5 bits.\n                                                                               : ... In instance aes_siv_core\n                core_ctrl_new = CTRL_IDLE;\n                              ^\n%Warning-WIDTH: data/full_repos/permissive/194918293/src/rtl/aes_siv_core.v:389: Operator CASE expects 5 bits on the Case expression, but Case expression\'s VARREF \'core_ctrl_reg\' generates 4 bits.\n                                                                               : ... In instance aes_siv_core\n      case (core_ctrl_reg)\n      ^~~~\n%Error: Exiting due to 2 error(s), 20 warning(s)\n'
module aes_siv_core(
                    input wire            clk,
                    input wire            reset_n,

                    input wire            encdec,
                    input wire [511 : 0]  key,
                    input wire            mode,
                    input wire            start,

                    input wire [15 :0]    ad_start,
                    input wire [15 :0]    ad_blocks,
                    input wire [7 : 0]    ad_final_size,

                    input wire [15 :0]    pc_start,
                    input wire [15 :0]    pc_blocks,
                    input wire [7 : 0]    pc_final_size,

                    output wire           cs,
                    output wire           we,
                    input wire            ack,
                    output wire [15 : 0]  addr,
                    input wire [127 : 0]  block_rd,
                    output wire [127 : 0] block_wr,

                    output wire [127 : 0] tag_in,
                    output wire [127 : 0] tag_out,
                    output wire           tag_ok,
                    output wire           ready
                   );





  localparam CTRL_IDLE          = 5'h00;
  localparam CTRL_S2V_INIT0     = 5'h01;
  localparam CTRL_S2V_INIT1     = 5'h02;
  localparam CTRL_S2V_FIRST0    = 5'h03;
  localparam CTRL_S2V_FIRST1    = 5'h04;
  localparam CTRL_S2V_NEXT0     = 5'h05;
  localparam CTRL_S2V_NEXT1     = 5'h06;
  localparam CTRL_S2V_FINAL0    = 5'h07;
  localparam CTRL_S2V_FINAL1    = 5'h08;
  localparam CTRL_S2V_FINALIZE0 = 5'h09;
  localparam CTRL_S2V_FINALIZE1 = 5'h0a;
  localparam CTRL_S2V_FINALIZE2 = 5'h0b;
  localparam CTRL_S2V_FINALIZE3 = 5'h0c;
  localparam CTRL_CTR_INIT0     = 5'h10;
  localparam CTRL_CTR_INIT1     = 5'h11;
  localparam CTRL_CTR_NEXT0     = 5'h12;
  localparam CTRL_CTR_NEXT1     = 5'h13;

  localparam AEAD_AES_SIV_CMAC_256 = 1'h0;
  localparam AEAD_AES_SIV_CMAC_512 = 1'h1;

  localparam CMAC_ZEROES = 2'h0;
  localparam CMAC_ONE    = 2'h1;
  localparam CMAC_BLOCK  = 2'h2;
  localparam CMAC_FINAL  = 2'h3;

  localparam D_CMAC = 2'h0;
  localparam D_DBL  = 2'h1;
  localparam D_XOR  = 2'h2;

  localparam AES_BLOCK_SIZE = 128;





  reg           ready_reg;
  reg           ready_new;
  reg           ready_we;

  reg [127 : 0] block_reg;
  reg           block_we;

  reg [127 : 0] d_reg;
  reg [127 : 0] d_new;
  reg           d_we;

  reg [127 : 0] v_reg;
  reg           v_we;

  reg [127 : 0] x_reg;
  reg [127 : 0] x_new;
  reg           x_we;

  reg           s2v_state_reg;
  reg           s2v_state_new;
  reg           s2v_state_we;

  reg [127 : 0] result_reg;
  reg [127 : 0] result_new;
  reg           result_we;

  reg [3 : 0]   core_ctrl_reg;
  reg [3 : 0]   core_ctrl_new;
  reg           core_ctrl_we;





  reg            aes_encdec;
  reg            aes_init;
  reg            aes_next;
  reg [255 : 0]  aes_key;
  reg            aes_keylen;
  reg [127 : 0]  aes_block;
  wire [127 : 0] aes_result;
  wire           aes_ready;
  wire           aes_valid;

  reg [255 : 0]  cmac_key;
  reg            cmac_keylen;
  reg [7 : 0]    cmac_final_size;
  reg            cmac_init;
  reg            cmac_next;
  reg            cmac_finalize;
  reg [127 : 0]  cmac_block;
  wire [127 : 0] cmac_result;
  wire           cmac_ready;
  wire           cmac_valid;
  reg [1 : 0]    cmac_inputs;

  reg            init_ctr;
  reg            update_ctr;

  reg            update_d;
  reg [1 : 0]    ctrl_d;

  reg            update_v;





  assign ready   = ready_reg;
  assign tag_out = v_reg;





  function [127 : 0] double(input [127 : 0] op);
    begin
      if (op[127])
        double = {op[126 : 0], 1'h0} ^ 128'h87;
      else
        double = {op[126 : 0], 1'h0};
    end
  endfunction






  aes_core aes(
               .clk(clk),
               .reset_n(reset_n),

               .encdec(aes_encdec),
               .init(aes_init),
               .next(aes_next),
               .ready(aes_ready),

               .key(aes_key),
               .keylen(aes_keylen),

               .block(aes_block),
               .result(aes_result),
               .result_valid(aes_valid)
               );


  cmac_core cmac(
                 .clk(clk),
                 .reset_n(reset_n),
                 .key(cmac_key),
                 .keylen(cmac_keylen),
                 .final_size(cmac_final_size),
                 .init(cmac_init),
                 .next(cmac_next),
                 .finalize(cmac_finalize),
                 .block(cmac_block),
                 .result(cmac_result),
                 .ready(cmac_ready),
                 .valid(cmac_valid)
                );









  always @ (posedge clk)
    begin: reg_update
      if (!reset_n)
        begin
          ready_reg      <= 1'h1;
          block_reg      <= 128'h0;
          result_reg     <= 128'h0;
          d_reg          <= 128'h0;
          v_reg          <= 128'h0;
          x_reg          <= 128'h0;
          s2v_state_reg  <= 1'h0;
          core_ctrl_reg  <= CTRL_IDLE;
        end
      else
        begin
          if (ready_we)
            ready_reg <= ready_new;

          if (block_we)
            block_reg <= block_rd;

          if (d_we)
            d_reg <= d_new;

          if (v_we)
            v_reg <= cmac_result;

          if (s2v_state_we)
            s2v_state_reg <= s2v_state_new;

          if (x_we)
            x_reg <= x_new;

          if (result_we)
            result_reg <= result_new;

          if (core_ctrl_we)
            core_ctrl_reg <= core_ctrl_new;
        end
    end









  always @*
    begin : siv_cmac_dp
      d_new = 128'h0;
      d_we  = 1'h0;
      v_we  = 1'h0;

      cmac_block  = 128'h0;
      cmac_key    = key[511 : 256];
      cmac_keylen = mode;

      case (cmac_inputs)
        CMAC_ZEROES: cmac_block = 128'h0;
        CMAC_ONE:    cmac_block = 128'h1;
        CMAC_BLOCK:  cmac_block = block_reg;
        CMAC_FINAL:  cmac_block = d_reg;
      endcase

      if (update_v)
        begin
          v_we  = 1'h1;
        end

      if (update_d)
        begin
          d_we = 1'h1;
          case (ctrl_d)
            D_CMAC: d_new = cmac_result;
            D_DBL:  d_new = double(d_reg);
            D_XOR:  d_new = d_reg ^ cmac_result;
            default
              begin
              end
          endcase
        end
    end









  always @*
    begin : ctr_dp
      reg [63 : 0] x_tmp;

      x_new = 128'h0;
      x_we  = 1'h0;



      if (init_ctr)
        begin
          x_new = {v_reg[127 : 64], 1'h0, v_reg[62 : 32], 1'h0, v_reg[30 : 0]};
          x_we  = 1'h1;
        end


      if (update_ctr)
        begin
          result_new = block_reg ^ aes_result;
          result_we  = 1'h1;
          x_tmp = x_reg[63 : 0] + 1'h1;
          x_new = {x_reg[127 : 64], x_tmp};
          x_we  = 1'h1;
        end
    end





  always @*
    begin : core_ctrl
      ready_new       = 1'h0;
      ready_we        = 1'h0;
      cmac_final_size = 8'h0;
      cmac_init       = 1'h0;
      cmac_next       = 1'h0;
      cmac_finalize   = 1'h0;
      s2v_state_new   = 1'h0;
      s2v_state_we    = 1'h0;
      init_ctr        = 1'h0;
      update_ctr      = 1'h0;
      block_we        = 1'h0;
      result_new      = 128'h0;
      result_we       = 1'h0;
      cmac_inputs     = CMAC_ZEROES;
      update_d        = 1'h0;
      ctrl_d          = D_CMAC;
      update_v        = 1'h0;
      core_ctrl_new   = CTRL_IDLE;
      core_ctrl_we    = 1'h0;

      case (core_ctrl_reg)
        CTRL_IDLE:
          begin
            if (start)
              begin
              end
          end

        CTRL_S2V_INIT0:
          begin
            if (cmac_ready)
              begin
                cmac_inputs     = CMAC_ZEROES;
                cmac_final_size = AES_BLOCK_SIZE;
                cmac_finalize   = 1'h1;
                core_ctrl_new   = CTRL_S2V_INIT1;
                core_ctrl_we    = 1'h1;
              end
          end


        CTRL_S2V_INIT1:
          begin
            cmac_inputs     = CMAC_ZEROES;
            cmac_final_size = AES_BLOCK_SIZE;
            if (cmac_ready)
              begin
                s2v_state_new = 1'h1;
                s2v_state_we  = 1'h1;
                update_d      = 1'h1;
                ctrl_d        = D_CMAC;
                ready_new     = 1'h1;
                ready_we      = 1'h1;
                core_ctrl_new = CTRL_IDLE;
                core_ctrl_we  = 1'h1;
              end
          end


        CTRL_S2V_FIRST0:
          begin
            if (cmac_ready)
              begin
                cmac_next     = 1'h1;
                cmac_inputs   = CMAC_BLOCK;
                core_ctrl_new = CTRL_S2V_FIRST1;
                core_ctrl_we  = 1'h1;
              end
          end


        CTRL_S2V_FIRST1:
          begin
            cmac_inputs = CMAC_BLOCK;
            if (cmac_ready)
              begin
                ready_new     = 1'h1;
                ready_we      = 1'h1;
                core_ctrl_new = CTRL_IDLE;
                core_ctrl_we  = 1'h1;
              end
          end


        CTRL_S2V_NEXT0:
          begin
            cmac_next     = 1'h1;
            cmac_inputs   = CMAC_BLOCK;
            core_ctrl_new = CTRL_S2V_NEXT1;
            core_ctrl_we  = 1'h1;
          end


        CTRL_S2V_NEXT1:
          begin
            cmac_inputs = CMAC_BLOCK;
            if (cmac_ready)
              begin
                ready_new     = 1'h1;
                ready_we      = 1'h1;
                core_ctrl_new = CTRL_IDLE;
                core_ctrl_we  = 1'h1;
              end
          end


        CTRL_S2V_FINAL0:
          begin
            update_d        = 1'h1;
            ctrl_d          = D_DBL;
            cmac_finalize   = 1'h1;
            cmac_inputs     = CMAC_BLOCK;
            cmac_final_size = ad_final_size;
            core_ctrl_new   = CTRL_S2V_FINAL1;
            core_ctrl_we    = 1'h1;
          end


        CTRL_S2V_FINAL1:
          begin
            cmac_inputs     = CMAC_BLOCK;
            cmac_final_size = ad_final_size;
            if (cmac_ready)
              begin
                update_d      = 1'h1;
                ctrl_d        = D_XOR;
                ready_new     = 1'h1;
                ready_we      = 1'h1;
                core_ctrl_new = CTRL_IDLE;
                core_ctrl_we  = 1'h1;
              end
          end


        CTRL_S2V_FINALIZE0:
          begin

            if (!s2v_state_reg)
              begin
                cmac_init       = 1'h1;
                core_ctrl_new   = CTRL_S2V_FINALIZE1;
                core_ctrl_we    = 1'h1;
              end
            else
              begin
                core_ctrl_new = CTRL_S2V_FINALIZE3;
                core_ctrl_we  = 1'h1;
              end
          end


        CTRL_S2V_FINALIZE1:
          begin

            if (cmac_ready)
              begin
                cmac_finalize   = 1'h1;
                cmac_inputs     = CMAC_ONE;
                cmac_final_size = AES_BLOCK_SIZE;
                core_ctrl_new   = CTRL_S2V_FINALIZE2;
                core_ctrl_we    = 1'h1;
              end
          end



        CTRL_S2V_FINALIZE2:
          begin
            cmac_inputs     = CMAC_ONE;
            cmac_final_size = AES_BLOCK_SIZE;
            if (cmac_ready)
              begin
                update_v      = 1'h1;
                ready_new     = 1'h1;
                ready_we      = 1'h1;
                core_ctrl_new = CTRL_IDLE;
                core_ctrl_we  = 1'h1;
              end
          end



        CTRL_S2V_FINALIZE3:
          begin
            ready_new     = 1'h1;
            ready_we      = 1'h1;
            core_ctrl_new = CTRL_IDLE;
            core_ctrl_we  = 1'h1;
          end


        CTRL_CTR_INIT0:
          begin
            init_ctr      = 1'h1;
            core_ctrl_new = CTRL_CTR_INIT1;
            core_ctrl_we  = 1'h1;
          end


        CTRL_CTR_INIT1:
          begin
            if (aes_ready)
              begin
                ready_new     = 1'h1;
                ready_we      = 1'h1;
                core_ctrl_new = CTRL_IDLE;
                core_ctrl_we  = 1'h1;
              end
          end


        CTRL_CTR_NEXT0:
          begin
            core_ctrl_new = CTRL_CTR_NEXT1;
            core_ctrl_we  = 1'h1;
          end


        CTRL_CTR_NEXT1:
          begin
            if (aes_ready)
              begin
                update_ctr    = 1'h1;
                result_we     = 1'h1;
                ready_new     = 1'h1;
                ready_we      = 1'h1;
                core_ctrl_new = CTRL_IDLE;
                core_ctrl_we  = 1'h1;
              end
          end


        default:
          begin

          end
      endcase
    end
endmodule
module aes_siv_core(
                    input wire            clk,
                    input wire            reset_n,

                    input wire            encdec,
                    input wire [511 : 0]  key,
                    input wire            mode,
                    input wire            start,

                    input wire [15 :0]    ad_start,
                    input wire [15 :0]    ad_blocks,
                    input wire [7 : 0]    ad_final_size,

                    input wire [15 :0]    pc_start,
                    input wire [15 :0]    pc_blocks,
                    input wire [7 : 0]    pc_final_size,

                    output wire           cs,
                    output wire           we,
                    input wire            ack,
                    output wire [15 : 0]  addr,
                    input wire [127 : 0]  block_rd,
                    output wire [127 : 0] block_wr,

                    output wire [127 : 0] tag_in,
                    output wire [127 : 0] tag_out,
                    output wire           tag_ok,
                    output wire           ready
                   );






  localparam CTRL_IDLE          = 5'h00;
  localparam CTRL_S2V_INIT0     = 5'h01;
  localparam CTRL_S2V_INIT1     = 5'h02;
  localparam CTRL_S2V_FIRST0    = 5'h03;
  localparam CTRL_S2V_FIRST1    = 5'h04;
  localparam CTRL_S2V_NEXT0     = 5'h05;
  localparam CTRL_S2V_NEXT1     = 5'h06;
  localparam CTRL_S2V_FINAL0    = 5'h07;
  localparam CTRL_S2V_FINAL1    = 5'h08;
  localparam CTRL_S2V_FINALIZE0 = 5'h09;
  localparam CTRL_S2V_FINALIZE1 = 5'h0a;
  localparam CTRL_S2V_FINALIZE2 = 5'h0b;
  localparam CTRL_S2V_FINALIZE3 = 5'h0c;
  localparam CTRL_CTR_INIT0     = 5'h10;
  localparam CTRL_CTR_INIT1     = 5'h11;
  localparam CTRL_CTR_NEXT0     = 5'h12;
  localparam CTRL_CTR_NEXT1     = 5'h13;

  localparam AEAD_AES_SIV_CMAC_256 = 1'h0;
  localparam AEAD_AES_SIV_CMAC_512 = 1'h1;

  localparam CMAC_ZEROES = 2'h0;
  localparam CMAC_ONE    = 2'h1;
  localparam CMAC_BLOCK  = 2'h2;
  localparam CMAC_FINAL  = 2'h3;

  localparam D_CMAC = 2'h0;
  localparam D_DBL  = 2'h1;
  localparam D_XOR  = 2'h2;

  localparam AES_BLOCK_SIZE = 128;





  reg           ready_reg;
  reg           ready_new;
  reg           ready_we;

  reg [127 : 0] block_reg;
  reg           block_we;

  reg [127 : 0] d_reg;
  reg [127 : 0] d_new;
  reg           d_we;

  reg [127 : 0] v_reg;
  reg           v_we;

  reg [127 : 0] x_reg;
  reg [127 : 0] x_new;
  reg           x_we;

  reg           s2v_state_reg;
  reg           s2v_state_new;
  reg           s2v_state_we;

  reg [127 : 0] result_reg;
  reg [127 : 0] result_new;
  reg           result_we;

  reg [3 : 0]   core_ctrl_reg;
  reg [3 : 0]   core_ctrl_new;
  reg           core_ctrl_we;





  reg            aes_encdec;
  reg            aes_init;
  reg            aes_next;
  reg [255 : 0]  aes_key;
  reg            aes_keylen;
  reg [127 : 0]  aes_block;
  wire [127 : 0] aes_result;
  wire           aes_ready;
  wire           aes_valid;

  reg [255 : 0]  cmac_key;
  reg            cmac_keylen;
  reg [7 : 0]    cmac_final_size;
  reg            cmac_init;
  reg            cmac_next;
  reg            cmac_finalize;
  reg [127 : 0]  cmac_block;
  wire [127 : 0] cmac_result;
  wire           cmac_ready;
  wire           cmac_valid;
  reg [1 : 0]    cmac_inputs;

  reg            init_ctr;
  reg            update_ctr;

  reg            update_d;
  reg [1 : 0]    ctrl_d;

  reg            update_v;





  assign ready   = ready_reg;
  assign tag_out = v_reg;





  function [127 : 0] double(input [127 : 0] op);
    begin
      if (op[127])
        double = {op[126 : 0], 1'h0} ^ 128'h87;
      else
        double = {op[126 : 0], 1'h0};
    end
  endfunction






  aes_core aes(
               .clk(clk),
               .reset_n(reset_n),

               .encdec(aes_encdec),
               .init(aes_init),
               .next(aes_next),
               .ready(aes_ready),

               .key(aes_key),
               .keylen(aes_keylen),

               .block(aes_block),
               .result(aes_result),
               .result_valid(aes_valid)
               );


  cmac_core cmac(
                 .clk(clk),
                 .reset_n(reset_n),
                 .key(cmac_key),
                 .keylen(cmac_keylen),
                 .final_size(cmac_final_size),
                 .init(cmac_init),
                 .next(cmac_next),
                 .finalize(cmac_finalize),
                 .block(cmac_block),
                 .result(cmac_result),
                 .ready(cmac_ready),
                 .valid(cmac_valid)
                );









  always @ (posedge clk)
    begin: reg_update
      if (!reset_n)
        begin
          ready_reg      <= 1'h1;
          block_reg      <= 128'h0;
          result_reg     <= 128'h0;
          d_reg          <= 128'h0;
          v_reg          <= 128'h0;
          x_reg          <= 128'h0;
          s2v_state_reg  <= 1'h0;
          core_ctrl_reg  <= CTRL_IDLE;
        end
      else
        begin
          if (ready_we)
            ready_reg <= ready_new;

          if (block_we)
            block_reg <= block_rd;

          if (d_we)
            d_reg <= d_new;

          if (v_we)
            v_reg <= cmac_result;

          if (s2v_state_we)
            s2v_state_reg <= s2v_state_new;

          if (x_we)
            x_reg <= x_new;

          if (result_we)
            result_reg <= result_new;

          if (core_ctrl_we)
            core_ctrl_reg <= core_ctrl_new;
        end
    end









  always @*
    begin : siv_cmac_dp
      d_new = 128'h0;
      d_we  = 1'h0;
      v_we  = 1'h0;

      cmac_block  = 128'h0;
      cmac_key    = key[511 : 256];
      cmac_keylen = mode;

      case (cmac_inputs)
        CMAC_ZEROES: cmac_block = 128'h0;
        CMAC_ONE:    cmac_block = 128'h1;
        CMAC_BLOCK:  cmac_block = block_reg;
        CMAC_FINAL:  cmac_block = d_reg;
      endcase

      if (update_v)
        begin
          v_we  = 1'h1;
        end

      if (update_d)
        begin
          d_we = 1'h1;
          case (ctrl_d)
            D_CMAC: d_new = cmac_result;
            D_DBL:  d_new = double(d_reg);
            D_XOR:  d_new = d_reg ^ cmac_result;
            default
              begin
              end
          endcase
        end
    end









  always @*
    begin : ctr_dp
      reg [63 : 0] x_tmp;

      x_new = 128'h0;
      x_we  = 1'h0;



      if (init_ctr)
        begin
          x_new = {v_reg[127 : 64], 1'h0, v_reg[62 : 32], 1'h0, v_reg[30 : 0]};
          x_we  = 1'h1;
        end


      if (update_ctr)
        begin
          result_new = block_reg ^ aes_result;
          result_we  = 1'h1;
          x_tmp = x_reg[63 : 0] + 1'h1;
          x_new = {x_reg[127 : 64], x_tmp};
          x_we  = 1'h1;
        end
    end





  always @*
    begin : core_ctrl
      ready_new       = 1'h0;
      ready_we        = 1'h0;
      cmac_final_size = 8'h0;
      cmac_init       = 1'h0;
      cmac_next       = 1'h0;
      cmac_finalize   = 1'h0;
      s2v_state_new   = 1'h0;
      s2v_state_we    = 1'h0;
      init_ctr        = 1'h0;
      update_ctr      = 1'h0;
      block_we        = 1'h0;
      result_new      = 128'h0;
      result_we       = 1'h0;
      cmac_inputs     = CMAC_ZEROES;
      update_d        = 1'h0;
      ctrl_d          = D_CMAC;
      update_v        = 1'h0;
      core_ctrl_new   = CTRL_IDLE;
      core_ctrl_we    = 1'h0;

      case (core_ctrl_reg)
        CTRL_IDLE:
          begin
            if (start)
              begin
              end
          end

        CTRL_S2V_INIT0:
          begin
            if (cmac_ready)
              begin
                cmac_inputs     = CMAC_ZEROES;
                cmac_final_size = AES_BLOCK_SIZE;
                cmac_finalize   = 1'h1;
                core_ctrl_new   = CTRL_S2V_INIT1;
                core_ctrl_we    = 1'h1;
              end
          end


        CTRL_S2V_INIT1:
          begin
            cmac_inputs     = CMAC_ZEROES;
            cmac_final_size = AES_BLOCK_SIZE;
            if (cmac_ready)
              begin
                s2v_state_new = 1'h1;
                s2v_state_we  = 1'h1;
                update_d      = 1'h1;
                ctrl_d        = D_CMAC;
                ready_new     = 1'h1;
                ready_we      = 1'h1;
                core_ctrl_new = CTRL_IDLE;
                core_ctrl_we  = 1'h1;
              end
          end


        CTRL_S2V_FIRST0:
          begin
            if (cmac_ready)
              begin
                cmac_next     = 1'h1;
                cmac_inputs   = CMAC_BLOCK;
                core_ctrl_new = CTRL_S2V_FIRST1;
                core_ctrl_we  = 1'h1;
              end
          end


        CTRL_S2V_FIRST1:
          begin
            cmac_inputs = CMAC_BLOCK;
            if (cmac_ready)
              begin
                ready_new     = 1'h1;
                ready_we      = 1'h1;
                core_ctrl_new = CTRL_IDLE;
                core_ctrl_we  = 1'h1;
              end
          end


        CTRL_S2V_NEXT0:
          begin
            cmac_next     = 1'h1;
            cmac_inputs   = CMAC_BLOCK;
            core_ctrl_new = CTRL_S2V_NEXT1;
            core_ctrl_we  = 1'h1;
          end


        CTRL_S2V_NEXT1:
          begin
            cmac_inputs = CMAC_BLOCK;
            if (cmac_ready)
              begin
                ready_new     = 1'h1;
                ready_we      = 1'h1;
                core_ctrl_new = CTRL_IDLE;
                core_ctrl_we  = 1'h1;
              end
          end


        CTRL_S2V_FINAL0:
          begin
            update_d        = 1'h1;
            ctrl_d          = D_DBL;
            cmac_finalize   = 1'h1;
            cmac_inputs     = CMAC_BLOCK;
            cmac_final_size = ad_final_size;
            core_ctrl_new   = CTRL_S2V_FINAL1;
            core_ctrl_we    = 1'h1;
          end


        CTRL_S2V_FINAL1:
          begin
            cmac_inputs     = CMAC_BLOCK;
            cmac_final_size = ad_final_size;
            if (cmac_ready)
              begin
                update_d      = 1'h1;
                ctrl_d        = D_XOR;
                ready_new     = 1'h1;
                ready_we      = 1'h1;
                core_ctrl_new = CTRL_IDLE;
                core_ctrl_we  = 1'h1;
              end
          end


        CTRL_S2V_FINALIZE0:
          begin

            if (!s2v_state_reg)
              begin
                cmac_init       = 1'h1;
                core_ctrl_new   = CTRL_S2V_FINALIZE1;
                core_ctrl_we    = 1'h1;
              end
            else
              begin
                core_ctrl_new = CTRL_S2V_FINALIZE3;
                core_ctrl_we  = 1'h1;
              end
          end


        CTRL_S2V_FINALIZE1:
          begin

            if (cmac_ready)
              begin
                cmac_finalize   = 1'h1;
                cmac_inputs     = CMAC_ONE;
                cmac_final_size = AES_BLOCK_SIZE;
                core_ctrl_new   = CTRL_S2V_FINALIZE2;
                core_ctrl_we    = 1'h1;
              end
          end



        CTRL_S2V_FINALIZE2:
          begin
            cmac_inputs     = CMAC_ONE;
            cmac_final_size = AES_BLOCK_SIZE;
            if (cmac_ready)
              begin
                update_v      = 1'h1;
                ready_new     = 1'h1;
                ready_we      = 1'h1;
                core_ctrl_new = CTRL_IDLE;
                core_ctrl_we  = 1'h1;
              end
          end



        CTRL_S2V_FINALIZE3:
          begin
            ready_new     = 1'h1;
            ready_we      = 1'h1;
            core_ctrl_new = CTRL_IDLE;
            core_ctrl_we  = 1'h1;
          end


        CTRL_CTR_INIT0:
          begin
            init_ctr      = 1'h1;
            core_ctrl_new = CTRL_CTR_INIT1;
            core_ctrl_we  = 1'h1;
          end


        CTRL_CTR_INIT1:
          begin
            if (aes_ready)
              begin
                ready_new     = 1'h1;
                ready_we      = 1'h1;
                core_ctrl_new = CTRL_IDLE;
                core_ctrl_we  = 1'h1;
              end
          end


        CTRL_CTR_NEXT0:
          begin
            core_ctrl_new = CTRL_CTR_NEXT1;
            core_ctrl_we  = 1'h1;
          end


        CTRL_CTR_NEXT1:
          begin
            if (aes_ready)
              begin
                update_ctr    = 1'h1;
                result_we     = 1'h1;
                ready_new     = 1'h1;
                ready_we      = 1'h1;
                core_ctrl_new = CTRL_IDLE;
                core_ctrl_we  = 1'h1;
              end
          end


        default:
          begin

          end
      endcase
    end
endmodule