mercredi 29 mars 2023

HLS : Cellular Automata

So I have been trying to build the following, using Vitis HLS:

ca.hpp:

#include <cstdio>
#include <cinttypes>

#include "ap_axi_sdata.h"
#include "hls_stream.h"

#define N 8

typedef int DataType;

typedef hls::axis<DataType, 0, 0, 0> packet;
typedef hls::stream<packet> stream;

bool is_equal(DataType previous_state[3], DataType test[3]);
DataType rule30(DataType previous_state[3]);

template <typename T> void ca(T input[N], T output[N]);

ca.cpp:

#include "ca.hpp"

DataType rule30_111[3] = {1, 1, 1};
DataType rule30_110[3] = {1, 1, 0};
DataType rule30_101[3] = {1, 0, 1};
DataType rule30_011[3] = {0, 1, 1};
DataType rule30_100[3] = {1, 0, 0};
DataType rule30_010[3] = {0, 1, 0};
DataType rule30_001[3] = {0, 0, 1};
DataType rule30_000[3] = {0, 0, 0};

bool is_equal(DataType previous_state[3], DataType test[3]){
    int check = 1;
    for(int j = 0; j < 3; j++){
        check = previous_state[j]==test[j];
        if(check == 0){
            return 0;
        }
    }
    return 1;
}

DataType rule30(DataType previous_state[3]){
    if(is_equal(previous_state, rule30_111)){
        return 0;
    } else if(is_equal(previous_state, rule30_110)){
        return 0;
    } else if(is_equal(previous_state, rule30_101)){
        return 0;
    } else if(is_equal(previous_state, rule30_011)){
        return 1;
    } else if(is_equal(previous_state, rule30_001)){
        return 1;
    } else if(is_equal(previous_state, rule30_010)){
        return 1;
    } else if(is_equal(previous_state, rule30_100)){
        return 1;
    } else if(is_equal(previous_state, rule30_000)){
        return 0;
    } else {
        return -1;
    }
}

template <typename T> void ca(T input[N], T output[N]) {
    for(int i = 0; i < N; i++){
        if(i > 0 and i < N - 1){
            T previous_state[3] = {input[i - 1], input[i], input[i + 1]};
            output[i] = rule30(previous_state);
        }
    }
}

void cellular_autmata(stream &signal, stream &result) {
#pragma HLS INTERFACE axis port=signal
#pragma HLS INTERFACE axis port=result
#pragma HLS INTERFACE ap_ctrl_none port=return

    DataType in[N];
    DataType out[N];

read:
    for(int i = 0; i < N; i++){
        packet temp = signal.read();
        in[i] = temp.data;
    }

    ca<DataType>(in, out);

write:
    for(int i = 0; i < N; i++){
        packet temp;
        temp.data = out[i];
        ap_uint<1> last = 0;
        if(i == N - 1){
            last = 1;
        }
        temp.last = last;
        temp.keep = -1;
        result.write(temp);
    }
}

ca_tb.cpp:

#include "ca.hpp"

void sw_ca(DataType input[], DataType output[]) {
    for(int i = 0; i < N; i++){
        if(i > 0 and i < N - 1){
            DataType rule[3] = {input[i - 1], input[i], input[i + 1]};
            output[i] = rule30(rule);
        }
    }
}

int main(void) {
    /*initialise*/
    int i, err;

    DataType in[N] = {0,0,1,1,0,0,1,1};
    DataType out_sw[N];
    DataType out_hw[N];

    std::cout << "signal in:" << std::endl;
    for (i = 0; i < N; i++) {
        //in[i] = i % 2;
        out_sw[i] = 0;
        out_hw[i] = 0;
        std::cout << in[i] << " ";
    }
    std::cout << std::endl;

    std::cout << std::endl;

    /* software */
    sw_ca(in, out_sw);
    std::cout<<"software kernel complete\n"<<std::endl;

    /* hardware */
    ca<DataType>(in, out_hw);
    std::cout<<"hardware kernel complete\n"<<std::endl;

    /* comparison */
    err = 1;
    std::cout << "signal out:" << std::endl;
    for(i = 0; i < N; i++){
        if(out_sw[i] != out_hw[i]){
            err = 0;
        }
        std::cout << out_hw[i] << " ";
    }
    std::cout<<std::endl;

    if (err == 1) {
        printf("Test successful!\r\n");
        return 0;
    }
    printf("Test failed\r\n");
    return 1;
}

Testbench runs fine...

And am repeatedly getting the error from vitis when trying to synthesize:

ERROR: [HLS 214-157] Top function not found: there is no function named 'ca' cellular_automata:cellular_automata Mar 29, 2023, 3:14:13 PM

Would massively appreciate any pointers here!

So for this system, I would expect a Vivado IP to be generated, but the Vitis compilation is halted with the error shown above

Aucun commentaire:

Enregistrer un commentaire