module emesh_pack
  #(parameter AW = 64,
    parameter PW = 144)
   (
    //Command Inputs
    input [3:0]      opcode_in,
    input [3:0]      length_in,//burst length(1-16)
    input [2:0]      size_in,//size of each transfer
    input [7:3]      user_in, //user control field
    //Address/Data
    input [AW-1:0]   dstaddr_in, //destination address
    input [AW-1:0]   srcaddr_in, //source address (for reads)
    input [2*AW-1:0] data_in, //data
    //Output packet
    output [PW-1:0]  packet_out
    );

   //############################################
   // Command Field
   //############################################
   wire [15:0] 	     cmd_out;

   assign cmd_out[3:0]   = opcode_in[3:0];
   assign cmd_out[7:4]   = length_in[3:0];
   assign cmd_out[10:8]  = size_in[2:0];
   assign cmd_out[15:11] = user_in[7:3];

   //Decode (only write indicator needed)
   emesh_decode enoc_decode (//Inputs
			    .cmd_in		(cmd_out[15:0]),
			    // Outputs
			    .cmd_write		(cmd_write),
			    .cmd_write_stop	(),
			    .cmd_read		(),
			    .cmd_atomic_add	(),
			    .cmd_atomic_and	(),
			    .cmd_atomic_or	(),
			    .cmd_atomic_xor	(),
			    .cmd_cas		(),
			    .cmd_opcode		(),
			    .cmd_length		(),
			    .cmd_size		(),
			    .cmd_user		());

   generate
      //############################
      // 16-Bit ("lite/apb like")
      //############################
      if(AW==16) begin : aw16
	 if(PW==40) begin : p40
	    assign packet_out[7:0]   = cmd_out[7:0];
	    assign packet_out[23:8]  = dstaddr_in[15:0];
	    assign packet_out[39:24] = cmd_write ? data_in[15:0]:
				                   srcaddr_in[15:0];
	 end
	 else begin: perror
	    initial
	      $display ("Combo not supported (PW=%ds AW==%ds)", PW,AW);
	 end
      end // block: aw16
      //######################
      // 32-Bit
      //######################
      if(AW==32) begin : aw32
	 if(PW==80) begin: p80
	    assign packet_out[15:0]   = cmd_out[15:0];
	    assign packet_out[47:16]  = dstaddr_in[31:0];
	    assign packet_out[79:48]  = cmd_write ? data_in[31:0] :
					            srcaddr_in[31:0];
	 end
	 else if(PW==112) begin: p112
	    assign packet_out[15:0]    = cmd_out[15:0];
	    assign packet_out[47:16]   = dstaddr_in[31:0];
	    assign packet_out[79:48]   = cmd_write ? data_in[31:0] :
					             srcaddr_in[31:0];
	    assign packet_out[111:80]  = data_in[63:32];
	 end
	 else begin: perror
	    initial
	      $display ("Combo not supported (PW=%ds AW==%ds)", PW,AW);
	 end
      end // block: aw32
      //######################
      // 64-Bit
      //######################
      if(AW==64) begin : aw64
	 if(PW==144) begin: p144
	    assign packet_out[15:0]    = cmd_out[15:0];
	    assign packet_out[47:16]   = dstaddr_in[31:0];
	    assign packet_out[111:48]  = cmd_write ? data_in[63:0] :
					             srcaddr_in[63:0];
	    assign packet_out[143:112] = dstaddr_in[63:32];
	 end
	 else if(PW==208) begin: p208
	    assign packet_out[15:0]    = cmd_out[15:0];
	    assign packet_out[47:16]   = dstaddr_in[31:0];
	    assign packet_out[111:48]  = cmd_write ? data_in[63:0] :
					             srcaddr_in[63:0];
	    assign packet_out[143:112] = dstaddr_in[63:32];
	    assign packet_out[207:144] = data_in[127:64];
	 end
	 else begin: perror
	    initial
	      $display ("Combo not supported (PW=%ds AW==%ds)", PW,AW);
	 end
      end // block: aw64
      //######################
      // 128-Bit
      //######################
      if(AW==128) begin : aw128
	 if(PW==272) begin: p272
	    assign packet_out[15:0]    = cmd_out[15:0];
	    assign packet_out[47:16]   = dstaddr_in[31:0];
	    assign packet_out[111:48]  = cmd_write ? data_in[63:0] :
					             srcaddr_in[63:0];
	    assign packet_out[143:112] = dstaddr_in[63:32];
	    assign packet_out[207:144] = cmd_write ? data_in[127:64] :
					             srcaddr_in[127:64];
	    assign packet_out[271:208] = dstaddr_in[127:64];
	 end
	 else if(PW==400) begin: p400
	    assign packet_out[15:0]    = cmd_out[15:0];
	    assign packet_out[47:16]   = dstaddr_in[31:0];
	    assign packet_out[111:48]  = cmd_write ? data_in[63:0] :
					             srcaddr_in[63:0];
	    assign packet_out[143:112] = dstaddr_in[63:32];
	    assign packet_out[207:144] = cmd_write ? data_in[127:64] :
					             srcaddr_in[127:64];
	    assign packet_out[271:208] = dstaddr_in[127:64];
	    assign packet_out[399:272] = data_in[255:128];
	 end
	 else begin: perror
	    initial
	      $display ("Combo not supported (PW=%ds AW==%ds)", PW,AW);
	 end
      end // block: aw128
   endgenerate
endmodule // emesh_pack