c++vivadovivado-hls

Function log2l has no function body


I am new to Vivado HLS ( using Vivado HLS 2018.3 ). I am writing this code to generate a 16-bit CRC (Cyclic Redundancy Check) using a 128-bit message and 17-bit generator polynomial. Here in the source code, I am using log2l() in order to find out the number of bits. This code runs smoothly during C Simulation but during C Synthesis, it throws the error :

Function 'log2l' has no function body

Please see the full source code below :

#include "header.h"
#include "ap_int.h"
using namespace std;

int crc(ap_int<128>  dword,ap_int<17>  gen){

int l_gen = floor(log2l(gen) + 1);   
 
ap_int<136> dividend = dword << (l_gen-1); 

// shft specifies the no. of least significant bits not being XORed

int shft = (int) (floor(log2l(dividend))+1) - l_gen;

ap_int<16> rem;  //rem variable stores the CRC value

while (shft >= 0){

    // bitwise XOR the MSBs of dividend with generator
    // replace the operated MSBs from the dividend with
    // remainder generated
    rem = (dividend >> shft) ^ gen;//
    // (dividend & ((1 << shft) - 1)) : bits of dividend that were not XORed
    dividend = (dividend & ((1 << shft) - 1)) | (rem << shft); // new dividend

    // change shft variable
   shft = (int) (floor(log2l(dividend))+1) - l_gen;

}

// finally, AND the initial dividend with the remainder (=dividend)
ap_int<144> codeword;  //128 bit message plus 16 bit CRC = 144 bit
codeword = (dword << (l_gen - 1)) | dividend;
cout << "Remainder: " << dividend << endl;
cout << "Codeword to be sent : " << codeword << endl;

return 0 ;

}

The test bench that I am using is :

#include "header.h"
#include "ap_int.h"
using namespace std;

int crc(ap_int<128> , ap_int<17> );

int main()

{
    ap_int<128>dataword ;
    ap_int<17> generator;
    dataword = 36;
    generator = 13;
    crc(dataword, generator);
    cout<<" Majid wins";
    return 0;
}

The header file is :

#include<iostream>
#include<math.h>
#include "ap_fixed.h"
#include "hls_stream.h"

In C simulation, the output that I get is :

Remainder: 1
Codeword to be sent : 289
Majid wins

I am using only three files : source , testbench and header.

Please tell me why this code is not working in C Synthesis. Also if you find anything amiss in my code, please tell me. Thanks !


Solution

  • I suspect it has something to do with the inclusion of the math library. I guess Vivado HLS has some configurations or flags to supply in compilation and then in synthesis regarding the use of mathematical functions.

    Nevertheless, a simple and effective workaround would be to implement floor(log2(x)) yourself, something that looks as follows:

    template <typename T>
    unsigned int mylog2 (T val) {
    #pragma HLS PIPELINE II=1
        if (val == 0) return (1 << (val::size-1)); // A very big number, assuming T is always ap_int<>
        if (val == 1) return 0;
        unsigned int ret = 0;
        while (val > 1) {
            val >>= 1;
            ret++;
        }
        return ret;
    }
    

    I'm pretty sure that Vivado will optimize the function and generate a proper hardware module.

    Reference: How to do an integer log2() in C++?

    Edit: I added a Pipeline pragma in order to be sure to obtain a 1-cycle hardware module.