cornell-zhang/hcl-dialect

[Op] No data type extension for shift_left op causes incorrect results

Closed this issue · 0 comments

As the title mentioned, this problem is caused when shifting a binary value. If the result is still binary, it is a constant and will be removed by Vivado HLS as a redundant loop. In the following example, the first loop nest is totally eliminated.

void top(
  ap_uint<1> v0[1][16][16][1],
  ap_uint<1> v1[16][3][3][1],
  ap_fixed<20, 10> v2[16][16][16],
  ap_uint<16> v3[32][3][3][1],
  ap_fixed<20, 10> v4[8][8][32],
  ap_uint<32> v5[256][16],
  ap_fixed<20, 10> v6[256],
  ap_uint<32> v7[10][8],
  ap_fixed<20, 10> v8[10],
  ap_uint<16> v9[1][16][16][1]
) {	//
  ap_int<6> conv1[1][16][16][16];	//
  l_yy: for (int yy = 0; yy < 16; yy++) {	//
    l_xx: for (int xx = 0; xx < 16; xx++) {	//
      l_ff: for (int ff = 0; ff < 16; ff++) {	//
        ap_int<6> sum_rv;	//
        sum_rv = 0;	//
        l_conv1_ry: for (int conv1_ry = 0; conv1_ry < 3; conv1_ry++) {	//
          l_conv1_rx: for (int conv1_rx = 0; conv1_rx < 3; conv1_rx++) {	//
            ap_int<6> v17;
            if (((xx + conv1_rx) - 1) >= 0 && ((-(xx + conv1_rx)) + 16) >= 0 && ((yy + conv1_ry) - 1) >= 0 && ((-(yy + conv1_ry)) + 16) >= 0) {	//
              ap_uint<1> v18 = v0[0][((yy + conv1_ry) - 1)][((xx + conv1_rx) - 1)][0];	//
              ap_uint<1> v19 = v1[ff][conv1_ry][conv1_rx][0];	//
              ap_uint<1> v20 = v18 ^ v19;	//
              ap_int<32> v21 = v20;	//
              ap_int<32> v22 = 1 - v21;	//
              ap_uint<1> v23 = v22[0];	//
              ap_uint<1> v24 = 1;	//
              **!!!!ap_uint<1> v25 = v23 << v24;	// shift left!!!**
              ap_int<32> v26 = v25;	//
              ap_int<32> v27 = v26 - 1;	//
              ap_int<6> v28 = v27;	//
              v17 = v28;	//
            } else {
              ap_int<6> v29 = 0;	//
              v17 = v29;	//
            }
            ap_int<6> v30 = sum_rv;	//
            ap_int<6> v31 = v17 + v30;	//
            sum_rv = v31;	//
          }
        }
        ap_int<6> v32 = sum_rv;	//
        conv1[0][yy][xx][ff] = v32;	//
      }
    }
  }
  l_h: for (int h = 0; h < 16; h++) {	//
    l_w: for (int w = 0; w < 16; w++) {	//
      ap_uint<16> bn1_pack;	//
      bn1_pack = 0;	//
      l_loop_0: for (int loop_0 = 0; loop_0 < 16; loop_0++) {	//
        ap_int<6> v37 = conv1[0][h][w][((0 * 16) + loop_0)];	//
        ap_fixed<20, 10> v38 = v2[h][w][((0 * 16) + loop_0)];	//
        ap_fixed<16, 6> v39 = v37;	//
        ap_fixed<20, 10> v40 = v39;	//
        ap_uint<1> v41 = v40 > v38;	//
        ap_uint<1> v42 = 1;	//
        ap_uint<1> v43 = 0;	//
        ap_uint<1> v44 = v41 ? (ap_uint<1>)v42 : (ap_uint<1>)v43;	//
        ap_uint<16> v45 = bn1_pack;	//
        v45[loop_0] = v44;	//
        bn1_pack = v45;	//
      }
      ap_uint<16> v46 = bn1_pack;	//
      ap_uint<16> v47 = bn1_pack;	//
      v9[0][h][w][0] = v47;	//
    }
  }
}

To make it correct, the highlighted line should generate at least bitwidth-2 result.