data/full_repos/permissive/531341619/rtl/execute_control.v
1: b'%Warning-WIDTH: data/full_repos/permissive/531341619/rtl/execute_control.v:287: Operator ASSIGN expects 8 bits on the Assign RHS, but Assign RHS\'s SEL generates 12 bits.\n                                                                              : ... In instance execute_control\n            accum_addr_nxt              = i_execute_instruction_data[24:13];\n                                        ^\n                ... Use "/* verilator lint_off WIDTH */" and lint_on around source to disable this message.\n%Warning-WIDTH: data/full_repos/permissive/531341619/rtl/execute_control.v:315: Operator ASSIGN expects 15 bits on the Assign RHS, but Assign RHS\'s SEL generates 18 bits.\n                                                                              : ... In instance execute_control\n          buffer_rd_addr_nxt     = i_execute_instruction_data[30:13];\n                                 ^\n%Warning-WIDTH: data/full_repos/permissive/531341619/rtl/execute_control.v:327: Operator COND expects 10 bits on the Conditional True, but Conditional True\'s CONST \'2\'h2\' generates 2 bits.\n                                                                              : ... In instance execute_control\n          buffer_inc_param = (buffer_inc_inst_reg[4] ? 2\'b10:2\'b01);\n                                                     ^\n%Warning-WIDTH: data/full_repos/permissive/531341619/rtl/execute_control.v:327: Operator COND expects 10 bits on the Conditional False, but Conditional False\'s CONST \'2\'h1\' generates 2 bits.\n                                                                              : ... In instance execute_control\n          buffer_inc_param = (buffer_inc_inst_reg[4] ? 2\'b10:2\'b01);\n                                                     ^\n%Warning-WIDTH: data/full_repos/permissive/531341619/rtl/execute_control.v:328: Operator COND expects 10 bits on the Conditional True, but Conditional True\'s CONST \'2\'h2\' generates 2 bits.\n                                                                              : ... In instance execute_control\n          accum_inc_param = (accum_inc_inst_reg[4] ? 2\'b10:2\'b01);\n                                                   ^\n%Warning-WIDTH: data/full_repos/permissive/531341619/rtl/execute_control.v:328: Operator COND expects 10 bits on the Conditional False, but Conditional False\'s CONST \'2\'h1\' generates 2 bits.\n                                                                              : ... In instance execute_control\n          accum_inc_param = (accum_inc_inst_reg[4] ? 2\'b10:2\'b01);\n                                                   ^\n%Warning-WIDTH: data/full_repos/permissive/531341619/rtl/execute_control.v:330: Operator ASSIGN expects 8 bits on the Assign RHS, but Assign RHS\'s VARREF \'accum_inc\' generates 15 bits.\n                                                                              : ... In instance execute_control\n          accum_addr_nxt = accum_inc;\n                         ^\n%Warning-WIDTH: data/full_repos/permissive/531341619/rtl/execute_control.v:339: Operator ADD expects 32 or 10 bits on the LHS, but LHS\'s VARREF \'counter0_inst_reg\' generates 8 bits.\n                                                                              : ... In instance execute_control\n              buffer_inc_param = ((((counter0_inst_reg + 1) + buffer_inc_inst_reg[3:2])<<1\'b1)+buffer_inc_inst_reg[1:0]);\n                                                       ^\n%Warning-WIDTH: data/full_repos/permissive/531341619/rtl/execute_control.v:339: Operator ADD expects 32 or 10 bits on the RHS, but RHS\'s SEL generates 2 bits.\n                                                                              : ... In instance execute_control\n              buffer_inc_param = ((((counter0_inst_reg + 1) + buffer_inc_inst_reg[3:2])<<1\'b1)+buffer_inc_inst_reg[1:0]);\n                                                            ^\n%Warning-WIDTH: data/full_repos/permissive/531341619/rtl/execute_control.v:339: Operator ADD expects 32 or 10 bits on the RHS, but RHS\'s SEL generates 2 bits.\n                                                                              : ... In instance execute_control\n              buffer_inc_param = ((((counter0_inst_reg + 1) + buffer_inc_inst_reg[3:2])<<1\'b1)+buffer_inc_inst_reg[1:0]);\n                                                                                              ^\n%Warning-WIDTH: data/full_repos/permissive/531341619/rtl/execute_control.v:341: Operator ASSIGN expects 10 bits on the Assign RHS, but Assign RHS\'s SEL generates 2 bits.\n                                                                              : ... In instance execute_control\n              buffer_inc_param = buffer_inc_inst_reg[1:0];\n                               ^\n%Warning-WIDTH: data/full_repos/permissive/531341619/rtl/execute_control.v:343: Operator ADD expects 32 or 10 bits on the LHS, but LHS\'s VARREF \'counter0_inst_reg\' generates 8 bits.\n                                                                              : ... In instance execute_control\n              accum_inc_param = ((((counter0_inst_reg + 1) + accum_inc_inst_reg[3:2])<<1\'b1)+accum_inc_inst_reg[1:0]);\n                                                      ^\n%Warning-WIDTH: data/full_repos/permissive/531341619/rtl/execute_control.v:343: Operator ADD expects 32 or 10 bits on the RHS, but RHS\'s SEL generates 2 bits.\n                                                                              : ... In instance execute_control\n              accum_inc_param = ((((counter0_inst_reg + 1) + accum_inc_inst_reg[3:2])<<1\'b1)+accum_inc_inst_reg[1:0]);\n                                                           ^\n%Warning-WIDTH: data/full_repos/permissive/531341619/rtl/execute_control.v:343: Operator ADD expects 32 or 10 bits on the RHS, but RHS\'s SEL generates 2 bits.\n                                                                              : ... In instance execute_control\n              accum_inc_param = ((((counter0_inst_reg + 1) + accum_inc_inst_reg[3:2])<<1\'b1)+accum_inc_inst_reg[1:0]);\n                                                                                            ^\n%Warning-WIDTH: data/full_repos/permissive/531341619/rtl/execute_control.v:345: Operator ASSIGN expects 10 bits on the Assign RHS, but Assign RHS\'s SEL generates 2 bits.\n                                                                              : ... In instance execute_control\n              accum_inc_param = accum_inc_inst_reg[1:0];\n                              ^\n%Warning-WIDTH: data/full_repos/permissive/531341619/rtl/execute_control.v:348: Operator ASSIGN expects 8 bits on the Assign RHS, but Assign RHS\'s VARREF \'accum_inc\' generates 15 bits.\n                                                                              : ... In instance execute_control\n            accum_addr_nxt = accum_inc;\n                           ^\n%Error: data/full_repos/permissive/531341619/rtl/execute_control.v:382: Cannot find file containing module: \'variable_length_shift_register\'\n  variable_length_shift_register\n  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/531341619/rtl,data/full_repos/permissive/531341619/variable_length_shift_register\n             data/full_repos/permissive/531341619/rtl,data/full_repos/permissive/531341619/variable_length_shift_register.v\n             data/full_repos/permissive/531341619/rtl,data/full_repos/permissive/531341619/variable_length_shift_register.sv\n             variable_length_shift_register\n             variable_length_shift_register.v\n             variable_length_shift_register.sv\n             obj_dir/variable_length_shift_register\n             obj_dir/variable_length_shift_register.v\n             obj_dir/variable_length_shift_register.sv\n%Error: data/full_repos/permissive/531341619/rtl/execute_control.v:404: Cannot find file containing module: \'variable_length_shift_register\'\n    variable_length_shift_register\n    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/531341619/rtl/execute_control.v:422: Cannot find file containing module: \'variable_length_shift_register\'\n  variable_length_shift_register\n  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n%Warning-WIDTH: data/full_repos/permissive/531341619/rtl/execute_control.v:435: Operator ADD expects 15 bits on the RHS, but RHS\'s VARREF \'buffer_inc_param\' generates 10 bits.\n                                                                              : ... In instance execute_control\n  assign  buffer_inc = buffer_rd_addr_reg + buffer_inc_param;\n                                          ^\n%Warning-WIDTH: data/full_repos/permissive/531341619/rtl/execute_control.v:436: Operator ADD expects 15 bits on the LHS, but LHS\'s VARREF \'accum_addr_reg\' generates 8 bits.\n                                                                              : ... In instance execute_control\n  assign  accum_inc = accum_addr_reg + accum_inc_param;\n                                     ^\n%Warning-WIDTH: data/full_repos/permissive/531341619/rtl/execute_control.v:436: Operator ADD expects 15 bits on the RHS, but RHS\'s VARREF \'accum_inc_param\' generates 10 bits.\n                                                                              : ... In instance execute_control\n  assign  accum_inc = accum_addr_reg + accum_inc_param;\n                                     ^\n%Error: Exiting due to 3 error(s), 19 warning(s)\n'
module execute_control
#(
  parameter                                       QUNATIZED_MANTISSA_WIDTH = 7,
  parameter                                       EXPONENT_WIDTH = 8,

  parameter                                       AXI_WIDTH_USER =1,
  parameter                                       AXI_WIDTH_ID   =4,
  parameter                                       AXI_WIDTH_AD   =32,
  parameter                                       AXI_WIDTH_DA   =32,
  parameter                                       AXI_WIDTH_DS =(AXI_WIDTH_DA/8),
  parameter                                       AXI_LITE_WIDTH_AD   =32,
  parameter                                       AXI_LITE_WIDTH_DA   =32,
  parameter                                       AXI_LITE_WIDTH_DS =(AXI_LITE_WIDTH_DA/8),
  

  

  parameter                                       MAC_ACC_WIDTH = 48,
  parameter                                       BUFFER_ADDR_WIDTH = 15,
  parameter                                       ACCUM_DATA_WIDTH = 32,
  parameter                                       ACCUM_ADDR_WIDTH = 8,
  parameter                                       BIAS_ROM_ADDR = 8,
  

  parameter                                       PARAM_ROM_ADDR_WIDTH = 8
  

  
)
(
  input  wire                                     clk, 
  input  wire                                     rst_n,


  input  wire                                     i_execute_instruction_fifo_empty, 
  input  wire                                     i_activation_instruction_fifo_full,
  input  wire [31:0]                              i_execute_instruction_data,
  output wire                                     o_execute_instruction_fifo_rd_en,
  output wire                                     o_activation_instruction_fifo_wr_en,

  output wire                                     o_execute_idle,



  output wire                                     o_activation_rd_en,
  output wire [BUFFER_ADDR_WIDTH-1:0]             o_buffer_rd_addr,
  


  output wire                                     o_set_weight,



  output wire                                     o_bias_mode,
  output wire                                     o_accum_rd_en, 
  output wire                                     o_accum_wr_en,
  output wire [ACCUM_ADDR_WIDTH-1:0]              o_accum_addr, 
  output wire                                     o_set_bias,

  input  wire                                     i_execute_out_fifo_full,
  output wire                                     o_execute_out_fifo_wr_en
);

  localparam
    IDLE          = 5'b00001,
    BUSY          = 5'b00010,
    FETCHEXE      = 5'b00100,
    WAITVALID     = 5'b01000,
    WAITFINISH    = 5'b10000;
  

  reg [4:0]                                     state_reg;
  reg [4:0]                                     state_nxt;


  reg                                           execute_instruction_fifo_rd_en;
  reg                                           activation_instruction_fifo_wr_en;



  reg                                           activation_rd_en_reg;
  reg                                           activation_rd_en_nxt;
  reg [BUFFER_ADDR_WIDTH-1:0]                   buffer_rd_addr_reg;
  reg [BUFFER_ADDR_WIDTH-1:0]                   buffer_rd_addr_nxt;

  


  reg                                           set_weight_reg;
  reg                                           set_weight_nxt;




  reg                                           bias_mode_reg;
  reg                                           bias_mode_nxt;
  reg                                           bias_mode_inst_reg;
  reg                                           bias_mode_inst_nxt;
  reg                                           accum_rd_en_reg;
  reg                                           accum_rd_en_nxt;
  reg                                           accum_wr_en_reg;
  reg                                           accum_wr_en_nxt;
  reg [ACCUM_ADDR_WIDTH-1:0]                    accum_addr_reg;
  reg [ACCUM_ADDR_WIDTH-1:0]                    accum_addr_nxt;
  reg                                           set_bias_reg;
  reg                                           set_bias_nxt;

  reg                                           execute_out_fifo_wr_en_reg;
  reg                                           execute_out_fifo_wr_en_nxt;

  reg                                           final_mode_inst_reg;
  reg                                           final_mode_inst_nxt;
  

  
  reg [7:0]                                     counter0_inst_nxt;
  reg [7:0]                                     counter0_inst_reg;
  reg [7:0]                                     counter0_ptr_nxt;
  reg [7:0]                                     counter0_ptr_reg;  
  
  reg [7:0]                                     counter1_inst_nxt;
  reg [7:0]                                     counter1_inst_reg;
  reg [7:0]                                     counter1_ptr_nxt;
  reg [7:0]                                     counter1_ptr_reg;  
  
  reg [4:0]                                     buffer_inc_inst_nxt;
  reg [4:0]                                     buffer_inc_inst_reg;
  reg [4:0]                                     accum_inc_inst_nxt;
  reg [4:0]                                     accum_inc_inst_reg;
  
  wire [BUFFER_ADDR_WIDTH-1:0]                  buffer_inc;
  wire [BUFFER_ADDR_WIDTH-1:0]                  accum_inc;
  reg  [9:0]                                    buffer_inc_param;
  reg  [9:0]                                    accum_inc_param;
  
  wire                                          valid;
  reg                                           busy;
  
  always @(posedge clk)
  begin
    if (rst_n==1'b0) 
    begin
      state_reg <= IDLE;


      activation_rd_en_reg <= 'd0;
      buffer_rd_addr_reg <= 'd0;
      


      set_weight_reg <= 'd0;



      bias_mode_reg <= 'd0;
      bias_mode_inst_reg <= 'd0;
      accum_rd_en_reg <= 'd0;
      accum_wr_en_reg <= 'd0;
      accum_addr_reg <= 'd0; 
      set_bias_reg <= 'd0;

      execute_out_fifo_wr_en_reg <= 'd0;
      final_mode_inst_reg <= 'd0;

      counter0_inst_reg <= 'd0;        
      counter0_ptr_reg <= 'd0;
      counter1_inst_reg <= 'd0;
      counter1_ptr_reg <= 'd0; 
      buffer_inc_inst_reg <= 'd0;
      accum_inc_inst_reg <= 'd0;
    end
    else
    begin

      state_reg <= state_nxt;


      activation_rd_en_reg <= activation_rd_en_nxt;
      buffer_rd_addr_reg <= buffer_rd_addr_nxt;

      


      set_weight_reg <= set_weight_nxt;




      bias_mode_reg <= bias_mode_nxt;
      bias_mode_inst_reg <= bias_mode_inst_nxt;
      accum_rd_en_reg <= accum_rd_en_nxt;
      accum_wr_en_reg <= accum_wr_en_nxt;
      accum_addr_reg <= accum_addr_nxt;
      set_bias_reg <= set_bias_nxt;

      execute_out_fifo_wr_en_reg <= execute_out_fifo_wr_en_nxt;
      final_mode_inst_reg <= final_mode_inst_nxt;

    
      counter0_inst_reg <= counter0_inst_nxt;        
      counter0_ptr_reg <= counter0_ptr_nxt;
      counter1_inst_reg <= counter1_inst_nxt;
      counter1_ptr_reg <= counter1_ptr_nxt; 
      buffer_inc_inst_reg <= buffer_inc_inst_nxt;
      accum_inc_inst_reg <= accum_inc_inst_nxt;
    end
  end

  always @(*)
  begin
    busy = 1'b0;
    state_nxt = state_reg;


    execute_instruction_fifo_rd_en = 1'b0;
    activation_instruction_fifo_wr_en = 1'b0;



    activation_rd_en_nxt = activation_rd_en_reg;
    buffer_rd_addr_nxt = buffer_rd_addr_reg;

    


    set_weight_nxt = 1'b0;



    bias_mode_nxt = bias_mode_reg;
    bias_mode_inst_nxt = bias_mode_inst_reg;
    accum_rd_en_nxt = accum_rd_en_reg;
    accum_wr_en_nxt = accum_wr_en_reg;
    accum_addr_nxt = accum_addr_reg;
    set_bias_nxt = 1'b0;

    execute_out_fifo_wr_en_nxt = execute_out_fifo_wr_en_reg;
    final_mode_inst_nxt = final_mode_inst_reg;

  
    counter0_inst_nxt = counter0_inst_reg;
    counter0_ptr_nxt = counter0_ptr_reg;
    counter1_inst_nxt = counter1_inst_reg;
    counter1_ptr_nxt = counter1_ptr_reg; 
    buffer_inc_inst_nxt = buffer_inc_inst_reg;
    accum_inc_inst_nxt = accum_inc_inst_reg;
    buffer_inc_param = 'd0;
    accum_inc_param = 'd0;

    case (state_reg)
      IDLE:
      begin
        if(!i_execute_instruction_fifo_empty) 
        begin
          if(i_execute_instruction_data[31:29] == 3'b010)
          begin
            state_nxt = FETCHEXE;
            execute_instruction_fifo_rd_en = 1'b1;

            bias_mode_nxt              = i_execute_instruction_data[28];
            bias_mode_inst_nxt         = i_execute_instruction_data[28];
            final_mode_inst_nxt        = i_execute_instruction_data[27];
            set_weight_nxt             = i_execute_instruction_data[26];
            set_bias_nxt               = i_execute_instruction_data[25];
            
            accum_addr_nxt              = i_execute_instruction_data[24:13];
            counter0_inst_nxt           = i_execute_instruction_data[12:5];
            counter0_ptr_nxt            = i_execute_instruction_data[12:5];
            accum_inc_inst_nxt          = i_execute_instruction_data[4:0];
          end
          else
          begin
            if(!i_activation_instruction_fifo_full)
            begin
              execute_instruction_fifo_rd_en = 1'b1; 
              activation_instruction_fifo_wr_en = 1'b1;
            end
          end        
        end
      end

      FETCHEXE:
      begin
        if(!i_execute_instruction_fifo_empty)
        begin
          state_nxt = BUSY;
          execute_instruction_fifo_rd_en = 1'b1;

          execute_out_fifo_wr_en_nxt = final_mode_inst_reg;
          accum_wr_en_nxt           = !final_mode_inst_reg;
          accum_rd_en_nxt           = !bias_mode_inst_reg;
          activation_rd_en_nxt      = 1'b1;
          
          buffer_rd_addr_nxt     = i_execute_instruction_data[30:13];
          counter1_inst_nxt      = i_execute_instruction_data[12:5];
          counter1_ptr_nxt       = i_execute_instruction_data[12:5];
          buffer_inc_inst_nxt    = i_execute_instruction_data[4:0];
        end
      end

      BUSY:
      begin
        if(counter0_ptr_reg != 'b0)
        begin
          counter0_ptr_nxt = counter0_ptr_reg - 1;
          buffer_inc_param = (buffer_inc_inst_reg[4] ? 2'b10:2'b01);
          accum_inc_param = (accum_inc_inst_reg[4] ? 2'b10:2'b01);
          buffer_rd_addr_nxt = buffer_inc;
          accum_addr_nxt = accum_inc;
        end
        else
        begin
          if(counter1_ptr_reg != 'b0)
          begin
            counter1_ptr_nxt = counter1_ptr_reg - 1;
            counter0_ptr_nxt = counter0_inst_reg;
            if(buffer_inc_inst_reg[4])
              buffer_inc_param = ((((counter0_inst_reg + 1) + buffer_inc_inst_reg[3:2])<<1'b1)+buffer_inc_inst_reg[1:0]);
            else 
              buffer_inc_param = buffer_inc_inst_reg[1:0];
            if(accum_inc_inst_reg[4])
              accum_inc_param = ((((counter0_inst_reg + 1) + accum_inc_inst_reg[3:2])<<1'b1)+accum_inc_inst_reg[1:0]);
            else
              accum_inc_param = accum_inc_inst_reg[1:0];

            buffer_rd_addr_nxt = buffer_inc;
            accum_addr_nxt = accum_inc;
          end
          else
          begin
            state_nxt = WAITFINISH;
            execute_out_fifo_wr_en_nxt = 1'b0;
            accum_wr_en_nxt = 1'b0;
            accum_rd_en_nxt = 1'b0;
            activation_rd_en_nxt = 1'b0;
            if({i_execute_instruction_data[31:29], i_execute_instruction_data[26:25]} == 5'b01000)
            begin
              state_nxt = IDLE;
            end
            else
            begin
              busy = 1'b1;
              state_nxt = WAITFINISH;
            end
          end
        end 
      end

      WAITFINISH:
      begin
        if(valid)
        begin
          state_nxt = IDLE;
        end
      end

      default : state_nxt = IDLE;
    endcase
  end

  variable_length_shift_register
  #(
    .DATA_WIDTH(ACCUM_ADDR_WIDTH+3),
    .DELAY(19) 
  ) accumulator_control_signal_delay_0
  (
    .clk(clk),
    .rst_n(rst_n),
    .i_data({
    accum_rd_en_reg,
    accum_wr_en_reg,
    accum_addr_reg,
    execute_out_fifo_wr_en_reg
    }),
    .o_data({
    o_accum_rd_en,
    o_accum_wr_en,
    o_accum_addr,
    o_execute_out_fifo_wr_en
    })
  );

    variable_length_shift_register
  #(
    .DATA_WIDTH(2),
    .DELAY(19) 
  ) accumulator_control_signal_delay_1
  (
    .clk(clk),
    .rst_n(rst_n),
    .i_data({
    bias_mode_reg,
    set_bias_reg
    }),
    .o_data({
    o_bias_mode,
    o_set_bias
    })
  );

  variable_length_shift_register
  #(
    .DATA_WIDTH(1),
    .DELAY(40) 
  ) execute_valid
  (
    .clk(clk),
    .rst_n(rst_n),
    .i_data(busy),
    .o_data(valid)
  );


  assign  buffer_inc = buffer_rd_addr_reg + buffer_inc_param;
  assign  accum_inc = accum_addr_reg + accum_inc_param;



  assign o_execute_instruction_fifo_rd_en = execute_instruction_fifo_rd_en;
  assign o_activation_instruction_fifo_wr_en = activation_instruction_fifo_wr_en;



  assign o_activation_rd_en = activation_rd_en_reg;
  assign o_buffer_rd_addr = buffer_rd_addr_reg;
  


  assign o_set_weight = set_weight_reg;

  assign o_execute_idle = state_reg[0];

endmodule
module execute_control
#(
  parameter                                       QUNATIZED_MANTISSA_WIDTH = 7,
  parameter                                       EXPONENT_WIDTH = 8,

  parameter                                       AXI_WIDTH_USER =1,
  parameter                                       AXI_WIDTH_ID   =4,
  parameter                                       AXI_WIDTH_AD   =32,
  parameter                                       AXI_WIDTH_DA   =32,
  parameter                                       AXI_WIDTH_DS =(AXI_WIDTH_DA/8),
  parameter                                       AXI_LITE_WIDTH_AD   =32,
  parameter                                       AXI_LITE_WIDTH_DA   =32,
  parameter                                       AXI_LITE_WIDTH_DS =(AXI_LITE_WIDTH_DA/8),
  

  

  parameter                                       MAC_ACC_WIDTH = 48,
  parameter                                       BUFFER_ADDR_WIDTH = 15,
  parameter                                       ACCUM_DATA_WIDTH = 32,
  parameter                                       ACCUM_ADDR_WIDTH = 8,
  parameter                                       BIAS_ROM_ADDR = 8,
  

  parameter                                       PARAM_ROM_ADDR_WIDTH = 8
  

  
)
(
  input  wire                                     clk, 
  input  wire                                     rst_n,


  input  wire                                     i_execute_instruction_fifo_empty, 
  input  wire                                     i_activation_instruction_fifo_full,
  input  wire [31:0]                              i_execute_instruction_data,
  output wire                                     o_execute_instruction_fifo_rd_en,
  output wire                                     o_activation_instruction_fifo_wr_en,

  output wire                                     o_execute_idle,



  output wire                                     o_activation_rd_en,
  output wire [BUFFER_ADDR_WIDTH-1:0]             o_buffer_rd_addr,
  


  output wire                                     o_set_weight,



  output wire                                     o_bias_mode,
  output wire                                     o_accum_rd_en, 
  output wire                                     o_accum_wr_en,
  output wire [ACCUM_ADDR_WIDTH-1:0]              o_accum_addr, 
  output wire                                     o_set_bias,

  input  wire                                     i_execute_out_fifo_full,
  output wire                                     o_execute_out_fifo_wr_en
);


  localparam
    IDLE          = 5'b00001,
    BUSY          = 5'b00010,
    FETCHEXE      = 5'b00100,
    WAITVALID     = 5'b01000,
    WAITFINISH    = 5'b10000;
  

  reg [4:0]                                     state_reg;
  reg [4:0]                                     state_nxt;


  reg                                           execute_instruction_fifo_rd_en;
  reg                                           activation_instruction_fifo_wr_en;



  reg                                           activation_rd_en_reg;
  reg                                           activation_rd_en_nxt;
  reg [BUFFER_ADDR_WIDTH-1:0]                   buffer_rd_addr_reg;
  reg [BUFFER_ADDR_WIDTH-1:0]                   buffer_rd_addr_nxt;

  


  reg                                           set_weight_reg;
  reg                                           set_weight_nxt;




  reg                                           bias_mode_reg;
  reg                                           bias_mode_nxt;
  reg                                           bias_mode_inst_reg;
  reg                                           bias_mode_inst_nxt;
  reg                                           accum_rd_en_reg;
  reg                                           accum_rd_en_nxt;
  reg                                           accum_wr_en_reg;
  reg                                           accum_wr_en_nxt;
  reg [ACCUM_ADDR_WIDTH-1:0]                    accum_addr_reg;
  reg [ACCUM_ADDR_WIDTH-1:0]                    accum_addr_nxt;
  reg                                           set_bias_reg;
  reg                                           set_bias_nxt;

  reg                                           execute_out_fifo_wr_en_reg;
  reg                                           execute_out_fifo_wr_en_nxt;

  reg                                           final_mode_inst_reg;
  reg                                           final_mode_inst_nxt;
  

  
  reg [7:0]                                     counter0_inst_nxt;
  reg [7:0]                                     counter0_inst_reg;
  reg [7:0]                                     counter0_ptr_nxt;
  reg [7:0]                                     counter0_ptr_reg;  
  
  reg [7:0]                                     counter1_inst_nxt;
  reg [7:0]                                     counter1_inst_reg;
  reg [7:0]                                     counter1_ptr_nxt;
  reg [7:0]                                     counter1_ptr_reg;  
  
  reg [4:0]                                     buffer_inc_inst_nxt;
  reg [4:0]                                     buffer_inc_inst_reg;
  reg [4:0]                                     accum_inc_inst_nxt;
  reg [4:0]                                     accum_inc_inst_reg;
  
  wire [BUFFER_ADDR_WIDTH-1:0]                  buffer_inc;
  wire [BUFFER_ADDR_WIDTH-1:0]                  accum_inc;
  reg  [9:0]                                    buffer_inc_param;
  reg  [9:0]                                    accum_inc_param;
  
  wire                                          valid;
  reg                                           busy;
  
  always @(posedge clk)
  begin
    if (rst_n==1'b0) 
    begin
      state_reg <= IDLE;


      activation_rd_en_reg <= 'd0;
      buffer_rd_addr_reg <= 'd0;
      


      set_weight_reg <= 'd0;



      bias_mode_reg <= 'd0;
      bias_mode_inst_reg <= 'd0;
      accum_rd_en_reg <= 'd0;
      accum_wr_en_reg <= 'd0;
      accum_addr_reg <= 'd0; 
      set_bias_reg <= 'd0;

      execute_out_fifo_wr_en_reg <= 'd0;
      final_mode_inst_reg <= 'd0;

      counter0_inst_reg <= 'd0;        
      counter0_ptr_reg <= 'd0;
      counter1_inst_reg <= 'd0;
      counter1_ptr_reg <= 'd0; 
      buffer_inc_inst_reg <= 'd0;
      accum_inc_inst_reg <= 'd0;
    end
    else
    begin

      state_reg <= state_nxt;


      activation_rd_en_reg <= activation_rd_en_nxt;
      buffer_rd_addr_reg <= buffer_rd_addr_nxt;

      


      set_weight_reg <= set_weight_nxt;




      bias_mode_reg <= bias_mode_nxt;
      bias_mode_inst_reg <= bias_mode_inst_nxt;
      accum_rd_en_reg <= accum_rd_en_nxt;
      accum_wr_en_reg <= accum_wr_en_nxt;
      accum_addr_reg <= accum_addr_nxt;
      set_bias_reg <= set_bias_nxt;

      execute_out_fifo_wr_en_reg <= execute_out_fifo_wr_en_nxt;
      final_mode_inst_reg <= final_mode_inst_nxt;

    
      counter0_inst_reg <= counter0_inst_nxt;        
      counter0_ptr_reg <= counter0_ptr_nxt;
      counter1_inst_reg <= counter1_inst_nxt;
      counter1_ptr_reg <= counter1_ptr_nxt; 
      buffer_inc_inst_reg <= buffer_inc_inst_nxt;
      accum_inc_inst_reg <= accum_inc_inst_nxt;
    end
  end

  always @(*)
  begin
    busy = 1'b0;
    state_nxt = state_reg;


    execute_instruction_fifo_rd_en = 1'b0;
    activation_instruction_fifo_wr_en = 1'b0;



    activation_rd_en_nxt = activation_rd_en_reg;
    buffer_rd_addr_nxt = buffer_rd_addr_reg;

    


    set_weight_nxt = 1'b0;



    bias_mode_nxt = bias_mode_reg;
    bias_mode_inst_nxt = bias_mode_inst_reg;
    accum_rd_en_nxt = accum_rd_en_reg;
    accum_wr_en_nxt = accum_wr_en_reg;
    accum_addr_nxt = accum_addr_reg;
    set_bias_nxt = 1'b0;

    execute_out_fifo_wr_en_nxt = execute_out_fifo_wr_en_reg;
    final_mode_inst_nxt = final_mode_inst_reg;

  
    counter0_inst_nxt = counter0_inst_reg;
    counter0_ptr_nxt = counter0_ptr_reg;
    counter1_inst_nxt = counter1_inst_reg;
    counter1_ptr_nxt = counter1_ptr_reg; 
    buffer_inc_inst_nxt = buffer_inc_inst_reg;
    accum_inc_inst_nxt = accum_inc_inst_reg;
    buffer_inc_param = 'd0;
    accum_inc_param = 'd0;

    case (state_reg)
      IDLE:
      begin
        if(!i_execute_instruction_fifo_empty) 
        begin
          if(i_execute_instruction_data[31:29] == 3'b010)
          begin
            state_nxt = FETCHEXE;
            execute_instruction_fifo_rd_en = 1'b1;

            bias_mode_nxt              = i_execute_instruction_data[28];
            bias_mode_inst_nxt         = i_execute_instruction_data[28];
            final_mode_inst_nxt        = i_execute_instruction_data[27];
            set_weight_nxt             = i_execute_instruction_data[26];
            set_bias_nxt               = i_execute_instruction_data[25];
            
            accum_addr_nxt              = i_execute_instruction_data[24:13];
            counter0_inst_nxt           = i_execute_instruction_data[12:5];
            counter0_ptr_nxt            = i_execute_instruction_data[12:5];
            accum_inc_inst_nxt          = i_execute_instruction_data[4:0];
          end
          else
          begin
            if(!i_activation_instruction_fifo_full)
            begin
              execute_instruction_fifo_rd_en = 1'b1; 
              activation_instruction_fifo_wr_en = 1'b1;
            end
          end        
        end
      end

      FETCHEXE:
      begin
        if(!i_execute_instruction_fifo_empty)
        begin
          state_nxt = BUSY;
          execute_instruction_fifo_rd_en = 1'b1;

          execute_out_fifo_wr_en_nxt = final_mode_inst_reg;
          accum_wr_en_nxt           = !final_mode_inst_reg;
          accum_rd_en_nxt           = !bias_mode_inst_reg;
          activation_rd_en_nxt      = 1'b1;
          
          buffer_rd_addr_nxt     = i_execute_instruction_data[30:13];
          counter1_inst_nxt      = i_execute_instruction_data[12:5];
          counter1_ptr_nxt       = i_execute_instruction_data[12:5];
          buffer_inc_inst_nxt    = i_execute_instruction_data[4:0];
        end
      end

      BUSY:
      begin
        if(counter0_ptr_reg != 'b0)
        begin
          counter0_ptr_nxt = counter0_ptr_reg - 1;
          buffer_inc_param = (buffer_inc_inst_reg[4] ? 2'b10:2'b01);
          accum_inc_param = (accum_inc_inst_reg[4] ? 2'b10:2'b01);
          buffer_rd_addr_nxt = buffer_inc;
          accum_addr_nxt = accum_inc;
        end
        else
        begin
          if(counter1_ptr_reg != 'b0)
          begin
            counter1_ptr_nxt = counter1_ptr_reg - 1;
            counter0_ptr_nxt = counter0_inst_reg;
            if(buffer_inc_inst_reg[4])
              buffer_inc_param = ((((counter0_inst_reg + 1) + buffer_inc_inst_reg[3:2])<<1'b1)+buffer_inc_inst_reg[1:0]);
            else 
              buffer_inc_param = buffer_inc_inst_reg[1:0];
            if(accum_inc_inst_reg[4])
              accum_inc_param = ((((counter0_inst_reg + 1) + accum_inc_inst_reg[3:2])<<1'b1)+accum_inc_inst_reg[1:0]);
            else
              accum_inc_param = accum_inc_inst_reg[1:0];

            buffer_rd_addr_nxt = buffer_inc;
            accum_addr_nxt = accum_inc;
          end
          else
          begin
            state_nxt = WAITFINISH;
            execute_out_fifo_wr_en_nxt = 1'b0;
            accum_wr_en_nxt = 1'b0;
            accum_rd_en_nxt = 1'b0;
            activation_rd_en_nxt = 1'b0;
            if({i_execute_instruction_data[31:29], i_execute_instruction_data[26:25]} == 5'b01000)
            begin
              state_nxt = IDLE;
            end
            else
            begin
              busy = 1'b1;
              state_nxt = WAITFINISH;
            end
          end
        end 
      end

      WAITFINISH:
      begin
        if(valid)
        begin
          state_nxt = IDLE;
        end
      end

      default : state_nxt = IDLE;
    endcase
  end

  variable_length_shift_register
  #(
    .DATA_WIDTH(ACCUM_ADDR_WIDTH+3),
    .DELAY(19) 
  ) accumulator_control_signal_delay_0
  (
    .clk(clk),
    .rst_n(rst_n),
    .i_data({
    accum_rd_en_reg,
    accum_wr_en_reg,
    accum_addr_reg,
    execute_out_fifo_wr_en_reg
    }),
    .o_data({
    o_accum_rd_en,
    o_accum_wr_en,
    o_accum_addr,
    o_execute_out_fifo_wr_en
    })
  );

    variable_length_shift_register
  #(
    .DATA_WIDTH(2),
    .DELAY(19) 
  ) accumulator_control_signal_delay_1
  (
    .clk(clk),
    .rst_n(rst_n),
    .i_data({
    bias_mode_reg,
    set_bias_reg
    }),
    .o_data({
    o_bias_mode,
    o_set_bias
    })
  );

  variable_length_shift_register
  #(
    .DATA_WIDTH(1),
    .DELAY(40) 
  ) execute_valid
  (
    .clk(clk),
    .rst_n(rst_n),
    .i_data(busy),
    .o_data(valid)
  );


  assign  buffer_inc = buffer_rd_addr_reg + buffer_inc_param;
  assign  accum_inc = accum_addr_reg + accum_inc_param;



  assign o_execute_instruction_fifo_rd_en = execute_instruction_fifo_rd_en;
  assign o_activation_instruction_fifo_wr_en = activation_instruction_fifo_wr_en;



  assign o_activation_rd_en = activation_rd_en_reg;
  assign o_buffer_rd_addr = buffer_rd_addr_reg;
  


  assign o_set_weight = set_weight_reg;

  assign o_execute_idle = state_reg[0];

endmodule