data/full_repos/permissive/155713836/src/strawman_rx_fsm.v
1: b'%Warning-WIDTH: data/full_repos/permissive/155713836/src/strawman_rx_fsm.v:104: Operator ASSIGNW expects 4 bits on the Assign RHS, but Assign RHS\'s SEL generates 3 bits.\n                                                                              : ... In instance strawman_rx_fsm\n  assign cmd_value = i_flit[4:2];\n                   ^\n                ... Use "/* verilator lint_off WIDTH */" and lint_on around source to disable this message.\n%Warning-WIDTH: data/full_repos/permissive/155713836/src/strawman_rx_fsm.v:105: Operator ASSIGNW expects 4 bits on the Assign RHS, but Assign RHS\'s SEL generates 3 bits.\n                                                                              : ... In instance strawman_rx_fsm\n  assign length = i_flit[7:5];\n                ^\n%Warning-WIDTH: data/full_repos/permissive/155713836/src/strawman_rx_fsm.v:109: Operator ASSIGNW expects 4 bits on the Assign RHS, but Assign RHS\'s SEL generates 3 bits.\n                                                                              : ... In instance strawman_rx_fsm\n  assign cmd_value2 = i_flit2[4:2];\n                    ^\n%Warning-WIDTH: data/full_repos/permissive/155713836/src/strawman_rx_fsm.v:110: Operator ASSIGNW expects 4 bits on the Assign RHS, but Assign RHS\'s SEL generates 3 bits.\n                                                                              : ... In instance strawman_rx_fsm\n  assign length2 = i_flit2[7:5];\n                 ^\n%Warning-WIDTH: data/full_repos/permissive/155713836/src/strawman_rx_fsm.v:175: Operator EQ expects 4 bits on the RHS, but RHS\'s CONST \'3\'h2\' generates 3 bits.\n                                                                              : ... In instance strawman_rx_fsm\n            end else if (cmd_value == 3\'b010) begin  \n                                   ^~\n%Warning-WIDTH: data/full_repos/permissive/155713836/src/strawman_rx_fsm.v:172: Operator EQ expects 4 bits on the RHS, but RHS\'s CONST \'3\'h1\' generates 3 bits.\n                                                                              : ... In instance strawman_rx_fsm\n            end else if (cmd_value == 3\'b001) begin  \n                                   ^~\n%Warning-WIDTH: data/full_repos/permissive/155713836/src/strawman_rx_fsm.v:169: Operator EQ expects 4 bits on the RHS, but RHS\'s CONST \'3\'h0\' generates 3 bits.\n                                                                              : ... In instance strawman_rx_fsm\n            if (cmd_value == 3\'b000) begin  \n                          ^~\n%Warning-WIDTH: data/full_repos/permissive/155713836/src/strawman_rx_fsm.v:189: Operator EQ expects 4 bits on the RHS, but RHS\'s CONST \'3\'h2\' generates 3 bits.\n                                                                              : ... In instance strawman_rx_fsm\n            end else if (cmd_value == 3\'b010) begin  \n                                   ^~\n%Warning-WIDTH: data/full_repos/permissive/155713836/src/strawman_rx_fsm.v:186: Operator EQ expects 4 bits on the RHS, but RHS\'s CONST \'3\'h1\' generates 3 bits.\n                                                                              : ... In instance strawman_rx_fsm\n            end else if (cmd_value == 3\'b001) begin  \n                                   ^~\n%Warning-WIDTH: data/full_repos/permissive/155713836/src/strawman_rx_fsm.v:183: Operator EQ expects 4 bits on the RHS, but RHS\'s CONST \'3\'h0\' generates 3 bits.\n                                                                              : ... In instance strawman_rx_fsm\n            if (cmd_value == 3\'b000) begin  \n                          ^~\n%Warning-WIDTH: data/full_repos/permissive/155713836/src/strawman_rx_fsm.v:223: Operator EQ expects 4 bits on the RHS, but RHS\'s CONST \'3\'h5\' generates 3 bits.\n                                                                              : ... In instance strawman_rx_fsm\n        end else if (length2 == 3\'b101) begin  \n                             ^~\n%Warning-WIDTH: data/full_repos/permissive/155713836/src/strawman_rx_fsm.v:221: Operator EQ expects 4 bits on the RHS, but RHS\'s CONST \'3\'h4\' generates 3 bits.\n                                                                              : ... In instance strawman_rx_fsm\n        end else if (length2 == 3\'b100) begin  \n                             ^~\n%Warning-WIDTH: data/full_repos/permissive/155713836/src/strawman_rx_fsm.v:219: Operator EQ expects 4 bits on the RHS, but RHS\'s CONST \'3\'h3\' generates 3 bits.\n                                                                              : ... In instance strawman_rx_fsm\n        end else if (length2 == 3\'b011) begin  \n                             ^~\n%Warning-WIDTH: data/full_repos/permissive/155713836/src/strawman_rx_fsm.v:217: Operator EQ expects 4 bits on the RHS, but RHS\'s CONST \'3\'h2\' generates 3 bits.\n                                                                              : ... In instance strawman_rx_fsm\n        end else if (length2 == 3\'b010) begin  \n                             ^~\n%Warning-WIDTH: data/full_repos/permissive/155713836/src/strawman_rx_fsm.v:215: Operator EQ expects 4 bits on the RHS, but RHS\'s CONST \'3\'h1\' generates 3 bits.\n                                                                              : ... In instance strawman_rx_fsm\n        end else if (length2 == 3\'b001) begin  \n                             ^~\n%Warning-WIDTH: data/full_repos/permissive/155713836/src/strawman_rx_fsm.v:213: Operator EQ expects 4 bits on the RHS, but RHS\'s CONST \'3\'h0\' generates 3 bits.\n                                                                              : ... In instance strawman_rx_fsm\n        if (length2 == 3\'b000) begin  \n                    ^~\n%Warning-WIDTH: data/full_repos/permissive/155713836/src/strawman_rx_fsm.v:254: Operator EQ expects 4 bits on the RHS, but RHS\'s CONST \'3\'h5\' generates 3 bits.\n                                                                              : ... In instance strawman_rx_fsm\n        end else if (length2 == 3\'b101) begin  \n                             ^~\n%Warning-WIDTH: data/full_repos/permissive/155713836/src/strawman_rx_fsm.v:252: Operator EQ expects 4 bits on the RHS, but RHS\'s CONST \'3\'h4\' generates 3 bits.\n                                                                              : ... In instance strawman_rx_fsm\n        end else if (length2 == 3\'b100) begin  \n                             ^~\n%Warning-WIDTH: data/full_repos/permissive/155713836/src/strawman_rx_fsm.v:250: Operator EQ expects 4 bits on the RHS, but RHS\'s CONST \'3\'h3\' generates 3 bits.\n                                                                              : ... In instance strawman_rx_fsm\n        end else if (length2 == 3\'b011) begin  \n                             ^~\n%Warning-WIDTH: data/full_repos/permissive/155713836/src/strawman_rx_fsm.v:248: Operator EQ expects 4 bits on the RHS, but RHS\'s CONST \'3\'h2\' generates 3 bits.\n                                                                              : ... In instance strawman_rx_fsm\n        end else if (length2 == 3\'b010) begin  \n                             ^~\n%Warning-WIDTH: data/full_repos/permissive/155713836/src/strawman_rx_fsm.v:246: Operator EQ expects 4 bits on the RHS, but RHS\'s CONST \'3\'h1\' generates 3 bits.\n                                                                              : ... In instance strawman_rx_fsm\n        end else if (length2 == 3\'b001) begin  \n                             ^~\n%Warning-WIDTH: data/full_repos/permissive/155713836/src/strawman_rx_fsm.v:244: Operator EQ expects 4 bits on the RHS, but RHS\'s CONST \'3\'h0\' generates 3 bits.\n                                                                              : ... In instance strawman_rx_fsm\n        if (length2 == 3\'b000) begin  \n                    ^~\n%Warning-WIDTH: data/full_repos/permissive/155713836/src/strawman_rx_fsm.v:359: Operator EQ expects 4 bits on the RHS, but RHS\'s CONST \'3\'h5\' generates 3 bits.\n                                                                              : ... In instance strawman_rx_fsm\n        end else if (length2 == 3\'b101) begin  \n                             ^~\n%Warning-WIDTH: data/full_repos/permissive/155713836/src/strawman_rx_fsm.v:357: Operator EQ expects 4 bits on the RHS, but RHS\'s CONST \'3\'h4\' generates 3 bits.\n                                                                              : ... In instance strawman_rx_fsm\n        end else if (length2 == 3\'b100) begin  \n                             ^~\n%Warning-WIDTH: data/full_repos/permissive/155713836/src/strawman_rx_fsm.v:355: Operator EQ expects 4 bits on the RHS, but RHS\'s CONST \'3\'h3\' generates 3 bits.\n                                                                              : ... In instance strawman_rx_fsm\n        end else if (length2 == 3\'b011) begin  \n                             ^~\n%Warning-WIDTH: data/full_repos/permissive/155713836/src/strawman_rx_fsm.v:353: Operator EQ expects 4 bits on the RHS, but RHS\'s CONST \'3\'h2\' generates 3 bits.\n                                                                              : ... In instance strawman_rx_fsm\n        end else if (length2 == 3\'b010) begin  \n                             ^~\n%Warning-WIDTH: data/full_repos/permissive/155713836/src/strawman_rx_fsm.v:351: Operator EQ expects 4 bits on the RHS, but RHS\'s CONST \'3\'h1\' generates 3 bits.\n                                                                              : ... In instance strawman_rx_fsm\n        end else if (length2 == 3\'b001) begin  \n                             ^~\n%Warning-WIDTH: data/full_repos/permissive/155713836/src/strawman_rx_fsm.v:349: Operator EQ expects 4 bits on the RHS, but RHS\'s CONST \'3\'h0\' generates 3 bits.\n                                                                              : ... In instance strawman_rx_fsm\n        if (length2 == 3\'b000) begin  \n                    ^~\n%Warning-WIDTH: data/full_repos/permissive/155713836/src/strawman_rx_fsm.v:395: Operator EQ expects 4 bits on the RHS, but RHS\'s CONST \'3\'h5\' generates 3 bits.\n                                                                              : ... In instance strawman_rx_fsm\n        end else if (length2 == 3\'b101) begin  \n                             ^~\n%Warning-WIDTH: data/full_repos/permissive/155713836/src/strawman_rx_fsm.v:393: Operator EQ expects 4 bits on the RHS, but RHS\'s CONST \'3\'h4\' generates 3 bits.\n                                                                              : ... In instance strawman_rx_fsm\n        end else if (length2 == 3\'b100) begin  \n                             ^~\n%Warning-WIDTH: data/full_repos/permissive/155713836/src/strawman_rx_fsm.v:391: Operator EQ expects 4 bits on the RHS, but RHS\'s CONST \'3\'h3\' generates 3 bits.\n                                                                              : ... In instance strawman_rx_fsm\n        end else if (length2 == 3\'b011) begin  \n                             ^~\n%Warning-WIDTH: data/full_repos/permissive/155713836/src/strawman_rx_fsm.v:389: Operator EQ expects 4 bits on the RHS, but RHS\'s CONST \'3\'h2\' generates 3 bits.\n                                                                              : ... In instance strawman_rx_fsm\n        end else if (length2 == 3\'b010) begin  \n                             ^~\n%Warning-WIDTH: data/full_repos/permissive/155713836/src/strawman_rx_fsm.v:387: Operator EQ expects 4 bits on the RHS, but RHS\'s CONST \'3\'h1\' generates 3 bits.\n                                                                              : ... In instance strawman_rx_fsm\n        end else if (length2 == 3\'b001) begin  \n                             ^~\n%Warning-WIDTH: data/full_repos/permissive/155713836/src/strawman_rx_fsm.v:385: Operator EQ expects 4 bits on the RHS, but RHS\'s CONST \'3\'h0\' generates 3 bits.\n                                                                              : ... In instance strawman_rx_fsm\n        if (length2 == 3\'b000) begin  \n                    ^~\n%Warning-WIDTH: data/full_repos/permissive/155713836/src/strawman_rx_fsm.v:411: Operator EQ expects 8 bits on the RHS, but RHS\'s VARREF \'cycles2hflit\' generates 6 bits.\n                                                                              : ... In instance strawman_rx_fsm\n          if ((counter + 1\'b1) == cycles2hflit) begin\n                               ^~\n%Warning-WIDTH: data/full_repos/permissive/155713836/src/strawman_rx_fsm.v:417: Operator ADD expects 8 bits on the RHS, but RHS\'s CONST \'2\'h2\' generates 2 bits.\n                                                                              : ... In instance strawman_rx_fsm\n          if ((counter + 2\'b10) == cycles2hflit) begin\n                       ^\n%Warning-WIDTH: data/full_repos/permissive/155713836/src/strawman_rx_fsm.v:417: Operator EQ expects 8 bits on the RHS, but RHS\'s VARREF \'cycles2hflit\' generates 6 bits.\n                                                                              : ... In instance strawman_rx_fsm\n          if ((counter + 2\'b10) == cycles2hflit) begin\n                                ^~\n%Error: Exiting due to 37 warning(s)\n'
module strawman_rx_fsm (
  clk,
  i_flit,
  i_slave_rx_ready,

  o_slave_rx_ren,

  o_address_valid,
  o_data_valid,
  o_data,
  o_address,

  o_cmd,
  o_cmd_valid,

  o_feature0,
  o_feature0_valid,

  o_feature1,
  o_feature1_valid,


  o_length,
  o_length_valid

);

  parameter FIFO_DEPTH = 32;
  parameter LOG2_FIFO_DEPTH = 5;
  parameter DATA_LINE_WIDTH = 40;
  parameter CONTROL_LINE_WIDTH = 0;
  parameter WORD_SIZE = 32;

  parameter LOG2_NUM_STATES = 4;

  parameter [LOG2_NUM_STATES-1:0] 
	IDLE  = 4'b0000,
	WRITE_REQ_HEADER = 4'b0001,
	WRITE_REQ_EX_HEADER = 4'b0010,
	WRITE_REQ_BODY = 4'b0011,
	READ_REQ_HEADER = 4'b0100,
	READ_REQ_EX_HEADER = 4'b0101,
	READ_REQ_EX_BODY = 4'b0110,
	READ_RESP_HEADER = 4'b0111,
	READ_RESP_EX_HEADER = 4'b1000,
	READ_RESP_BODY = 4'b1001;

  input clk;
  input [DATA_LINE_WIDTH-1:0] i_flit;
  input i_slave_rx_ready;
  output reg o_address_valid;
  output reg o_data_valid;
  output reg o_slave_rx_ren;
  output reg [WORD_SIZE-1:0] o_data;
  output reg [WORD_SIZE-1:0] o_address;

  output reg [2:0] o_cmd;
  output reg o_cmd_valid;

  output reg [5:0] o_feature0;
  output reg o_feature0_valid;

  output reg [5:0] o_feature1;
  output reg o_feature1_valid;

  output reg [2:0] o_length;
  output reg o_length_valid;


  reg [LOG2_NUM_STATES-1:0] current_state = 'b0;
  reg [LOG2_NUM_STATES-1:0] next_state = 'b0;



  reg [7:0] counter = 'b0;
  reg [5:0] cycles2hflit = 'b0;

  reg is_header_flit;

  reg protocol_select;
  wire valid_packet;
  wire [3:0] cmd_value;
  wire [3:0] length;

  reg [DATA_LINE_WIDTH-1:0] i_flit2, i_flit3;
  wire protocol_select2;
  wire valid_packet2;
  wire [3:0] cmd_value2;
  wire [3:0] length2;

  reg toggle_fsm = 1'b0;
  reg w_mode;

  assign valid_packet = i_flit[1];
  assign cmd_value = i_flit[4:2];
  assign length = i_flit[7:5];

  assign protocol_select2 = i_flit2[0];
  assign valid_packet2 = i_flit2[1];
  assign cmd_value2 = i_flit2[4:2];
  assign length2 = i_flit2[7:5];


  always @ (cycles2hflit) begin
    if (cycles2hflit == 'b0) begin
      is_header_flit = 1'b1;
    end else begin
      is_header_flit = 1'b0;
    end
  end

  always @(posedge clk) begin
    current_state <= next_state;
  end


  always @ (posedge clk) begin
    i_flit2 <= i_flit;
    i_flit3 <= i_flit2;
  end


  always @ (posedge clk) begin
    if ((current_state ==  WRITE_REQ_BODY) || (current_state ==  READ_RESP_BODY)) begin
      counter <= counter + 1'b1;
      toggle_fsm <= ~toggle_fsm;
    end else begin
      counter <= 'b0;
    end
  end


  always @(current_state, i_flit, counter, i_flit2) begin
    o_address_valid = 1'b0;
    o_data_valid = 1'b0;
    o_cmd_valid = 1'b0;
    o_feature0_valid = 1'b0;
    o_feature1_valid = 1'b0;
    o_length_valid = 1'b0;
    
    case (current_state)

      IDLE : begin

        o_slave_rx_ren = 1'b1;
        o_address_valid = 1'b0;
        o_data_valid = 1'b0;
        o_cmd_valid = 1'b0;
        o_feature0_valid = 1'b0;
        o_feature1_valid = 1'b0;
        cycles2hflit = 'b0;

        protocol_select = i_flit[0];



        if (valid_packet == 1'b1) begin

	  if (protocol_select == 1'b0) begin
            if (cmd_value == 3'b000) begin
              w_mode = 1'b0;
              next_state = READ_REQ_HEADER;
            end else if (cmd_value == 3'b001) begin
              w_mode = 1'b0;
              next_state = WRITE_REQ_HEADER;
            end else if (cmd_value == 3'b010) begin
              w_mode = 1'b0;
              next_state = READ_RESP_HEADER;
            end else begin
              next_state = IDLE;
            end

          end else begin
            if (cmd_value == 3'b000) begin
              w_mode = 1'b1;
              next_state = READ_REQ_EX_HEADER;
            end else if (cmd_value == 3'b001) begin
              w_mode = 1'b1;
              next_state = WRITE_REQ_EX_HEADER;
            end else if (cmd_value == 3'b010) begin
              w_mode = 1'b1;
              next_state = READ_RESP_EX_HEADER;
            end else begin
              next_state = IDLE;
            end
          end

        end else begin
          next_state = IDLE;
        end

      end

      WRITE_REQ_HEADER : begin
        o_slave_rx_ren = 1'b1;

        o_data_valid = 1'b0;
        o_address_valid = 1'b1;
        o_address = i_flit2[39:8];
        o_cmd_valid = 1'b1;
        o_cmd = i_flit2[4:2];


        if (length2 == 3'b000) begin
          cycles2hflit = 6'b1; 
        end else if (length2 == 3'b001) begin
          cycles2hflit = 6'b10;
        end else if (length2 == 3'b010) begin
          cycles2hflit = 6'b100;
        end else if (length2 == 3'b011) begin
          cycles2hflit = 6'b1000;
        end else if (length2 == 3'b100) begin
          cycles2hflit = 6'b10000;
        end else if (length2 == 3'b101) begin
          cycles2hflit = 6'b100000;
        end

        next_state = WRITE_REQ_BODY;

      end

      WRITE_REQ_EX_HEADER : begin
        o_slave_rx_ren = 1'b1;

        o_data_valid = 1'b0;
        o_address_valid = 1'b1;
        o_address = i_flit[31:0];
        o_cmd_valid = 1'b1;
        o_cmd = i_flit2[4:2];
        o_feature0_valid = 1'b1;
        o_feature0 = i_flit2[13:8];
        o_feature1_valid = 1'b1;
        o_feature1 = i_flit2[19:14];

        if (length2 == 3'b000) begin
          cycles2hflit = 6'b1; 
        end else if (length2 == 3'b001) begin
          cycles2hflit = 6'b10;
        end else if (length2 == 3'b010) begin
          cycles2hflit = 6'b100;
        end else if (length2 == 3'b011) begin
          cycles2hflit = 6'b1000;
        end else if (length2 == 3'b100) begin
          cycles2hflit = 6'b10000;
        end else if (length2 == 3'b101) begin
          cycles2hflit = 6'b100000;
        end

        next_state = WRITE_REQ_BODY;
      end


      WRITE_REQ_BODY : begin
        o_slave_rx_ren = 1'b1;
        o_address_valid = 1'b0;
        o_cmd_valid = 1'b0;
        o_data_valid = 1'b1;

        if (w_mode == 1'b1) begin
          o_data = i_flit[31:0];
        end else begin
          o_data = i_flit2[31:0];
        end

        if ((counter+1) >= cycles2hflit) begin
          next_state = IDLE;
        end else begin
          next_state = WRITE_REQ_BODY;
        end
      end


      READ_REQ_HEADER : begin
        o_slave_rx_ren = 1'b0;

        o_data_valid = 1'b0;
        o_address_valid = 1'b1;
        o_address = i_flit2[39:8];

        o_length = i_flit2[7:5];
        o_length_valid = 1'b1;

        o_cmd_valid = 1'b1;
        o_cmd = i_flit2[4:2];


        next_state = IDLE;
      end


      READ_REQ_EX_HEADER : begin
        o_slave_rx_ren = 1'b1;

        o_data_valid = 1'b0;


        o_length = i_flit2[7:5];
        o_length_valid = 1'b1;

        o_feature0_valid = 1'b1;
        o_feature0 = i_flit2[13:8];

        o_feature1_valid = 1'b1;
        o_feature1 = i_flit2[19:14];

        o_cmd_valid = 1'b1;
        o_cmd = i_flit2[4:2];

        o_address_valid = 1'b1;
        o_address = i_flit[31:0];

        next_state = IDLE;
      end




      READ_RESP_HEADER : begin
        o_slave_rx_ren = 1'b0;

        o_data_valid = 1'b1;
        o_address_valid = 1'b0;
        o_data = i_flit2[39:8];

        o_cmd_valid = 1'b1;
        o_cmd = i_flit2[4:2];


        if (length2 == 3'b000) begin
          cycles2hflit = 6'b0; 
        end else if (length2 == 3'b001) begin
          cycles2hflit = 6'b01;
        end else if (length2 == 3'b010) begin
          cycles2hflit = 6'b011;
        end else if (length2 == 3'b011) begin
          cycles2hflit = 6'b0111;
        end else if (length2 == 3'b100) begin
          cycles2hflit = 6'b01111;
        end else if (length2 == 3'b101) begin
          cycles2hflit = 6'b011111;
        end

        next_state = READ_RESP_BODY;

      end


      READ_RESP_EX_HEADER : begin
        o_slave_rx_ren = 1'b1;

        o_address_valid = 1'b0;

        o_data_valid = 1'b1;
        o_data = i_flit[31:0];

        o_cmd_valid = 1'b1;
        o_cmd = i_flit2[4:2];

        o_feature0_valid = 1'b1;
        o_feature0 = i_flit2[13:8];

        o_feature1_valid = 1'b1;
        o_feature1 = i_flit2[19:14];

        if (length2 == 3'b000) begin
          cycles2hflit = 6'b1; 
        end else if (length2 == 3'b001) begin
          cycles2hflit = 6'b10;
        end else if (length2 == 3'b010) begin
          cycles2hflit = 6'b100;
        end else if (length2 == 3'b011) begin
          cycles2hflit = 6'b1000;
        end else if (length2 == 3'b100) begin
          cycles2hflit = 6'b10000;
        end else if (length2 == 3'b101) begin
          cycles2hflit = 6'b100000;
        end

        next_state = READ_RESP_BODY;
      end


      READ_RESP_BODY : begin
        o_slave_rx_ren = 1'b1;
        o_address_valid = 1'b0;
        o_cmd_valid = 1'b0;
    
        o_data_valid = 1'b1;

        if (w_mode == 1'b0) begin
          if ((counter + 1'b1) == cycles2hflit) begin
            next_state = IDLE;
          end else begin
            next_state = READ_RESP_BODY;
          end
        end else begin
          if ((counter + 2'b10) == cycles2hflit) begin
            next_state = IDLE;
          end else begin
            next_state = READ_RESP_BODY;
          end
        end

        if (w_mode == 1'b1) begin
          o_data = i_flit[31:0];
        end else begin
          o_data = i_flit2[31:0];
        end

      end


      default: begin
        next_state = IDLE;
      end

    endcase
  end


  
endmodule
module strawman_rx_fsm (
  clk,
  i_flit,
  i_slave_rx_ready,

  o_slave_rx_ren,

  o_address_valid,
  o_data_valid,
  o_data,
  o_address,

  o_cmd,
  o_cmd_valid,

  o_feature0,
  o_feature0_valid,

  o_feature1,
  o_feature1_valid,


  o_length,
  o_length_valid

);


  parameter FIFO_DEPTH = 32;
  parameter LOG2_FIFO_DEPTH = 5;
  parameter DATA_LINE_WIDTH = 40;
  parameter CONTROL_LINE_WIDTH = 0;
  parameter WORD_SIZE = 32;

  parameter LOG2_NUM_STATES = 4;

  parameter [LOG2_NUM_STATES-1:0] 
	IDLE  = 4'b0000,
	WRITE_REQ_HEADER = 4'b0001,
	WRITE_REQ_EX_HEADER = 4'b0010,
	WRITE_REQ_BODY = 4'b0011,
	READ_REQ_HEADER = 4'b0100,
	READ_REQ_EX_HEADER = 4'b0101,
	READ_REQ_EX_BODY = 4'b0110,
	READ_RESP_HEADER = 4'b0111,
	READ_RESP_EX_HEADER = 4'b1000,
	READ_RESP_BODY = 4'b1001;

  input clk;
  input [DATA_LINE_WIDTH-1:0] i_flit;
  input i_slave_rx_ready;
  output reg o_address_valid;
  output reg o_data_valid;
  output reg o_slave_rx_ren;
  output reg [WORD_SIZE-1:0] o_data;
  output reg [WORD_SIZE-1:0] o_address;

  output reg [2:0] o_cmd;
  output reg o_cmd_valid;

  output reg [5:0] o_feature0;
  output reg o_feature0_valid;

  output reg [5:0] o_feature1;
  output reg o_feature1_valid;

  output reg [2:0] o_length;
  output reg o_length_valid;


  reg [LOG2_NUM_STATES-1:0] current_state = 'b0;
  reg [LOG2_NUM_STATES-1:0] next_state = 'b0;



  reg [7:0] counter = 'b0;
  reg [5:0] cycles2hflit = 'b0;

  reg is_header_flit;

  reg protocol_select;
  wire valid_packet;
  wire [3:0] cmd_value;
  wire [3:0] length;

  reg [DATA_LINE_WIDTH-1:0] i_flit2, i_flit3;
  wire protocol_select2;
  wire valid_packet2;
  wire [3:0] cmd_value2;
  wire [3:0] length2;

  reg toggle_fsm = 1'b0;
  reg w_mode;

  assign valid_packet = i_flit[1];
  assign cmd_value = i_flit[4:2];
  assign length = i_flit[7:5];

  assign protocol_select2 = i_flit2[0];
  assign valid_packet2 = i_flit2[1];
  assign cmd_value2 = i_flit2[4:2];
  assign length2 = i_flit2[7:5];


  always @ (cycles2hflit) begin
    if (cycles2hflit == 'b0) begin
      is_header_flit = 1'b1;
    end else begin
      is_header_flit = 1'b0;
    end
  end

  always @(posedge clk) begin
    current_state <= next_state;
  end


  always @ (posedge clk) begin
    i_flit2 <= i_flit;
    i_flit3 <= i_flit2;
  end


  always @ (posedge clk) begin
    if ((current_state ==  WRITE_REQ_BODY) || (current_state ==  READ_RESP_BODY)) begin
      counter <= counter + 1'b1;
      toggle_fsm <= ~toggle_fsm;
    end else begin
      counter <= 'b0;
    end
  end


  always @(current_state, i_flit, counter, i_flit2) begin
    o_address_valid = 1'b0;
    o_data_valid = 1'b0;
    o_cmd_valid = 1'b0;
    o_feature0_valid = 1'b0;
    o_feature1_valid = 1'b0;
    o_length_valid = 1'b0;
    
    case (current_state)

      IDLE : begin

        o_slave_rx_ren = 1'b1;
        o_address_valid = 1'b0;
        o_data_valid = 1'b0;
        o_cmd_valid = 1'b0;
        o_feature0_valid = 1'b0;
        o_feature1_valid = 1'b0;
        cycles2hflit = 'b0;

        protocol_select = i_flit[0];



        if (valid_packet == 1'b1) begin

	  if (protocol_select == 1'b0) begin
            if (cmd_value == 3'b000) begin
              w_mode = 1'b0;
              next_state = READ_REQ_HEADER;
            end else if (cmd_value == 3'b001) begin
              w_mode = 1'b0;
              next_state = WRITE_REQ_HEADER;
            end else if (cmd_value == 3'b010) begin
              w_mode = 1'b0;
              next_state = READ_RESP_HEADER;
            end else begin
              next_state = IDLE;
            end

          end else begin
            if (cmd_value == 3'b000) begin
              w_mode = 1'b1;
              next_state = READ_REQ_EX_HEADER;
            end else if (cmd_value == 3'b001) begin
              w_mode = 1'b1;
              next_state = WRITE_REQ_EX_HEADER;
            end else if (cmd_value == 3'b010) begin
              w_mode = 1'b1;
              next_state = READ_RESP_EX_HEADER;
            end else begin
              next_state = IDLE;
            end
          end

        end else begin
          next_state = IDLE;
        end

      end

      WRITE_REQ_HEADER : begin
        o_slave_rx_ren = 1'b1;

        o_data_valid = 1'b0;
        o_address_valid = 1'b1;
        o_address = i_flit2[39:8];
        o_cmd_valid = 1'b1;
        o_cmd = i_flit2[4:2];


        if (length2 == 3'b000) begin
          cycles2hflit = 6'b1; 
        end else if (length2 == 3'b001) begin
          cycles2hflit = 6'b10;
        end else if (length2 == 3'b010) begin
          cycles2hflit = 6'b100;
        end else if (length2 == 3'b011) begin
          cycles2hflit = 6'b1000;
        end else if (length2 == 3'b100) begin
          cycles2hflit = 6'b10000;
        end else if (length2 == 3'b101) begin
          cycles2hflit = 6'b100000;
        end

        next_state = WRITE_REQ_BODY;

      end

      WRITE_REQ_EX_HEADER : begin
        o_slave_rx_ren = 1'b1;

        o_data_valid = 1'b0;
        o_address_valid = 1'b1;
        o_address = i_flit[31:0];
        o_cmd_valid = 1'b1;
        o_cmd = i_flit2[4:2];
        o_feature0_valid = 1'b1;
        o_feature0 = i_flit2[13:8];
        o_feature1_valid = 1'b1;
        o_feature1 = i_flit2[19:14];

        if (length2 == 3'b000) begin
          cycles2hflit = 6'b1; 
        end else if (length2 == 3'b001) begin
          cycles2hflit = 6'b10;
        end else if (length2 == 3'b010) begin
          cycles2hflit = 6'b100;
        end else if (length2 == 3'b011) begin
          cycles2hflit = 6'b1000;
        end else if (length2 == 3'b100) begin
          cycles2hflit = 6'b10000;
        end else if (length2 == 3'b101) begin
          cycles2hflit = 6'b100000;
        end

        next_state = WRITE_REQ_BODY;
      end


      WRITE_REQ_BODY : begin
        o_slave_rx_ren = 1'b1;
        o_address_valid = 1'b0;
        o_cmd_valid = 1'b0;
        o_data_valid = 1'b1;

        if (w_mode == 1'b1) begin
          o_data = i_flit[31:0];
        end else begin
          o_data = i_flit2[31:0];
        end

        if ((counter+1) >= cycles2hflit) begin
          next_state = IDLE;
        end else begin
          next_state = WRITE_REQ_BODY;
        end
      end


      READ_REQ_HEADER : begin
        o_slave_rx_ren = 1'b0;

        o_data_valid = 1'b0;
        o_address_valid = 1'b1;
        o_address = i_flit2[39:8];

        o_length = i_flit2[7:5];
        o_length_valid = 1'b1;

        o_cmd_valid = 1'b1;
        o_cmd = i_flit2[4:2];


        next_state = IDLE;
      end


      READ_REQ_EX_HEADER : begin
        o_slave_rx_ren = 1'b1;

        o_data_valid = 1'b0;


        o_length = i_flit2[7:5];
        o_length_valid = 1'b1;

        o_feature0_valid = 1'b1;
        o_feature0 = i_flit2[13:8];

        o_feature1_valid = 1'b1;
        o_feature1 = i_flit2[19:14];

        o_cmd_valid = 1'b1;
        o_cmd = i_flit2[4:2];

        o_address_valid = 1'b1;
        o_address = i_flit[31:0];

        next_state = IDLE;
      end




      READ_RESP_HEADER : begin
        o_slave_rx_ren = 1'b0;

        o_data_valid = 1'b1;
        o_address_valid = 1'b0;
        o_data = i_flit2[39:8];

        o_cmd_valid = 1'b1;
        o_cmd = i_flit2[4:2];


        if (length2 == 3'b000) begin
          cycles2hflit = 6'b0; 
        end else if (length2 == 3'b001) begin
          cycles2hflit = 6'b01;
        end else if (length2 == 3'b010) begin
          cycles2hflit = 6'b011;
        end else if (length2 == 3'b011) begin
          cycles2hflit = 6'b0111;
        end else if (length2 == 3'b100) begin
          cycles2hflit = 6'b01111;
        end else if (length2 == 3'b101) begin
          cycles2hflit = 6'b011111;
        end

        next_state = READ_RESP_BODY;

      end


      READ_RESP_EX_HEADER : begin
        o_slave_rx_ren = 1'b1;

        o_address_valid = 1'b0;

        o_data_valid = 1'b1;
        o_data = i_flit[31:0];

        o_cmd_valid = 1'b1;
        o_cmd = i_flit2[4:2];

        o_feature0_valid = 1'b1;
        o_feature0 = i_flit2[13:8];

        o_feature1_valid = 1'b1;
        o_feature1 = i_flit2[19:14];

        if (length2 == 3'b000) begin
          cycles2hflit = 6'b1; 
        end else if (length2 == 3'b001) begin
          cycles2hflit = 6'b10;
        end else if (length2 == 3'b010) begin
          cycles2hflit = 6'b100;
        end else if (length2 == 3'b011) begin
          cycles2hflit = 6'b1000;
        end else if (length2 == 3'b100) begin
          cycles2hflit = 6'b10000;
        end else if (length2 == 3'b101) begin
          cycles2hflit = 6'b100000;
        end

        next_state = READ_RESP_BODY;
      end


      READ_RESP_BODY : begin
        o_slave_rx_ren = 1'b1;
        o_address_valid = 1'b0;
        o_cmd_valid = 1'b0;
    
        o_data_valid = 1'b1;

        if (w_mode == 1'b0) begin
          if ((counter + 1'b1) == cycles2hflit) begin
            next_state = IDLE;
          end else begin
            next_state = READ_RESP_BODY;
          end
        end else begin
          if ((counter + 2'b10) == cycles2hflit) begin
            next_state = IDLE;
          end else begin
            next_state = READ_RESP_BODY;
          end
        end

        if (w_mode == 1'b1) begin
          o_data = i_flit[31:0];
        end else begin
          o_data = i_flit2[31:0];
        end

      end


      default: begin
        next_state = IDLE;
      end

    endcase
  end


  
endmodule