void acc_vadd_hls ( volatile int *cmd, volatile int *resp, int a[4096], int b[4096], int result[4096] ) {_ssdm_SpecArrayDimSize(result,4096);_ssdm_SpecArrayDimSize(b,4096);_ssdm_SpecArrayDimSize(a,4096);
#pragma empty_line
#pragma HLS INTERFACE ap_ctrl_none port=return
#pragma HLS INTERFACE axis depth=16 port=cmd
#pragma HLS INTERFACE axis depth=16 port=resp
#pragma HLS INTERFACE bram depth=1024 port=a
#pragma HLS INTERFACE bram depth=1024 port=b
#pragma HLS INTERFACE bram depth=1024 port=result
#pragma empty_line
#pragma HLS RESOURCE variable=a core=RAM_1P_BRAM
#pragma HLS RESOURCE variable=b core=RAM_1P_BRAM
#pragma HLS RESOURCE variable=result core=RAM_1P_BRAM
#pragma empty_line
 int i,op, start,end;
 // Accumulate each channel
 op = *cmd; //get the start command
 end = *cmd;
 start = *cmd;
 if (op == 1)
  add_Loop: for (i = start; i < end; i++) {_ssdm_op_SpecLoopName("add_Loop");_ssdm_RegionBegin("add_Loop");
     result[i]= a[i] + b[i];
      if (i == end-1) {
       *resp= 1; //means I am done.
      }
 _ssdm_RegionEnd("add_Loop");}
 else if (op == 2)
  sub_Loop: for (i = start; i < end; i++) {_ssdm_op_SpecLoopName("sub_Loop");_ssdm_RegionBegin("sub_Loop");
     result[i]= b[i] + a[i];
      if (i == end-1) {
       *resp= 1; //means I am done.
      }
 _ssdm_RegionEnd("sub_Loop");}
}
void acc_vadd_hls ( volatile int *cmd, volatile int *resp, int a[4096], int b[4096], int result[4096] ) {_ssdm_SpecArrayDimSize(result,4096);_ssdm_SpecArrayDimSize(b,4096);_ssdm_SpecArrayDimSize(a,4096);

_ssdm_op_SpecInterface(0, "ap_ctrl_none", 0, 0, 0, 0, "", "", "");
_ssdm_op_SpecInterface(cmd, "axis", 0, 0, 0, 16, "", "", "");
_ssdm_op_SpecInterface(resp, "axis", 0, 0, 0, 16, "", "", "");
_ssdm_op_SpecInterface(a, "bram", 0, 0, 0, 1024, "", "", "");
_ssdm_op_SpecInterface(b, "bram", 0, 0, 0, 1024, "", "", "");
_ssdm_op_SpecInterface(result, "bram", 0, 0, 0, 1024, "", "", "");

_ssdm_op_SpecResource(a, "", "RAM_1P_BRAM", "", "", "", "");
_ssdm_op_SpecResource(b, "", "RAM_1P_BRAM", "", "", "", "");
_ssdm_op_SpecResource(result, "", "RAM_1P_BRAM", "", "", "", "");

 int i,op, start,end;
 // Accumulate each channel
 op = *cmd; //get the start command
 end = *cmd;
 start = *cmd;
 if (op == 1)
  add_Loop: for (i = start; i < end; i++) {_ssdm_op_SpecLoopName("add_Loop");_ssdm_RegionBegin("add_Loop");
     result[i]= a[i] + b[i];
      if (i == end-1) {
       *resp= 1; //means I am done.
      }
 _ssdm_RegionEnd("add_Loop");}
 else if (op == 2)
  sub_Loop: for (i = start; i < end; i++) {_ssdm_op_SpecLoopName("sub_Loop");_ssdm_RegionBegin("sub_Loop");
     result[i]= b[i] + a[i];
      if (i == end-1) {
       *resp= 1; //means I am done.
      }
 _ssdm_RegionEnd("sub_Loop");}
}
void dma_filter(volatile unsigned int input_config[0x58], volatile unsigned int output_config[0x58],
  volatile unsigned minAddress, bool reset){_ssdm_SpecArrayDimSize(input_config,0x58);_ssdm_SpecArrayDimSize(output_config,0x58);
_ssdm_op_SpecWire(&reset, "ap_none", 0, 0, 0, 1, "", "", "");

_ssdm_op_SpecWire(&minAddress, "s_axilite", 0, 0, 0, 0, "", "", "");

_ssdm_op_SpecWire(output_config, "m_axi", 0, 0, 0, 0, "", "", "");

_ssdm_op_SpecWire(input_config, "s_axilite", 0, 0, 0, 0, "", "", "");

 if(!reset){
  bool wait = true;
  int i;
  INITIAL_LOOP: for(i=0; i<0x58; i++){_ssdm_op_SpecLoopName("INITIAL_LOOP");_ssdm_RegionBegin("INITIAL_LOOP");
_ssdm_op_SpecPipeline(1, 1, 1, 0, "");
 input_config[i] = 0;
  _ssdm_RegionEnd("INITIAL_LOOP");}

  bool read_ready = false;
  bool write_ready = false;
  unsigned read_config = 0;
  bool read_enable = false;
  bool read_interrupts = false;
  unsigned read_address = 0;
  unsigned read_length = 0;

  unsigned write_config = 0;
  bool write_enable = false;
  bool write_interrupts = false;
  unsigned write_address = 0;
  unsigned write_length = 0;
  WAIT_LOOP: while(wait){_ssdm_op_SpecLoopName("WAIT_LOOP");_ssdm_RegionBegin("WAIT_LOOP");
   bool clear = false;
   unsigned read_config = input_config[0];
   bool read_enable = read_config &= 1;
   bool read_interrupts = read_config &= 4096;
   unsigned read_address = input_config[6];
   unsigned read_length = input_config[10];

   unsigned write_config = input_config[12];
   bool write_enable = write_config &= 1;
   bool write_interrupts = write_config &= 4096;
   unsigned write_address = input_config[18];
   unsigned write_length = input_config[22];

   if(!read_enable && !write_enable){
    continue;
   } else if(read_address == 0 && write_address==0){
    continue;
   }

   if(read_address > 0 && read_address < minAddress){
    continue;
   } else if(read_length == 0){
    continue;
   } else{
    read_ready = true;
   }

   if(write_address > 0 && write_address < minAddress){
    continue;
   } else if(write_length == 0){
    continue;
   } else{
    write_ready = true;
   }
   if(read_ready){
    //enable read dma block
    output_config[0] |= 1;
    //enable read interupts
    if(read_interrupts){
     output_config[0] |= 4096;
    }
    //write source address
    output_config[6] = read_address;
    output_config[10] = read_length;
    clear = true;
   }

   if(write_ready){
    //enable s2mm on write dma block
    output_config[12] |= 1;
    //enable write interrupts
    if(write_enable){
     output_config[12] |= 4096;
    }
    //write dest address
    output_config[18] = write_address;
    output_config[22] = write_length;
    clear = true;
   }

   if(clear){
    CLEAR_LOOP: for(i=0; i<0x58; i++){_ssdm_op_SpecLoopName("CLEAR_LOOP");_ssdm_RegionBegin("CLEAR_LOOP");
_ssdm_op_SpecPipeline(1, 1, 1, 0, "");
 input_config[i] = 0;
    _ssdm_RegionEnd("CLEAR_LOOP");}
   }
  _ssdm_RegionEnd("WAIT_LOOP");}

 }
}