anikau31 / systemc-clang

This is a Clang tool that parses SystemC models, and synthesizes Verilog from it.
Other
74 stars 19 forks source link

Assertions fail on threads with if conditions in for loops #387

Open zhuanhao-wu opened 1 year ago

zhuanhao-wu commented 1 year ago

In file: https://github.com/intel/systemc-compiler/blob/main/designs/tests/cthread/test_cthread_for_if.cpp#L27 The original C++ code:


    sc_signal<sc_uint<TIME_CNTR_WIDTH> >    sleep_time;
   //...
    void for_in_if3() 
    {
        sc_uint<4> arr[4];
        for (int i = 0; i < 4; i++) {  
            arr[i] =i;
        }               
        wait();

        while (true) {
            if (arr[sleep_time.read()])
            { 
                wait();         // 1
            } else {
                for (int i = 0; i < 4; i++) {  
                    wait();     // 2
                    arr[i] += 1;
                }
            }
        }
    }

Error message from the binary:

@@ name is sc_core for isRecordType
isNamespace
@@ name is sc_core for isSCCall:: CXXMemberCallSCCall 0 inNS 0
systemc-clang: /opt/clang-13.0.0/include/llvm/ADT/SmallVector.h:281: const T& llvm::SmallVectorTemplateCommon<T, <template-parameter-1-2> >::operator[](llvm::SmallVectorTemplateCommon<T, <template-parameter-1-2> >::size_type) const [with T = std::pair<const systemc_clang::SplitCFGBlock*, systemc_clang::SupplementaryInfo>; <template-parameter-1-2> = void; llvm::SmallVectorTemplateCommon<T, <template-parameter-1-2> >::const_reference = const std::pair<const systemc_clang::SplitCFGBlock*, systemc_clang::SupplementaryInfo>&; llvm::SmallVectorTemplateCommon<T, <template-parameter-1-2> >::size_type = long unsigned int]: Assertion `idx < size()' failed.

A similar issue occurs with the other thread in the same file:

    void for_with_if3()
    {
        int l = 1;
        s = 0;
        wait();

        while (true) {

            for (int i = 0; i < 4; i++) {
                if (l < s.read()) l++;
                wait();                     // 1

                if (l > s.read()) {
                    l--;
                } else {
                    wait();                 // 2
                }
            }

            for (int i = 0; i < 3; ++i) {
                s = l;
                wait();                     // 3
            }
        }
    }

with output

systemc-clang: /opt/clang-13.0.0/include/llvm/ADT/SmallVector.h:281: const T& llvm::SmallVectorTemplateCommon<T, <template-parameter-1-2> >::operator[](llvm::SmallVectorTemplateCommon<T, <template-parameter-1-2> >::size_type) const [with T = std::pair<const systemc_clang::SplitCFGBlock*, systemc_clang::SupplementaryInfo>; <template-parameter-1-2> = void; llvm::SmallVectorTemplateCommon<T, <template-parameter-1-2> >::const_reference = const std::pair<const systemc_clang::SplitCFGBlock*, systemc_clang::SupplementaryInfo>&; llvm::SmallVectorTemplateCommon<T, <template-parameter-1-2> >::size_type = long unsigned int]: Assertion `idx < size()' failed.
rseac commented 1 year ago

I confirmed that the SCCFG is being generated correctly, and the false paths are also correct.

@mayagokhale Would it be possible to get some help in understanding the construction logic here: https://github.com/anikau31/systemc-clang/blob/scratchllnl/plugins/hdl/HDLThread.cpp#L450-L451

It appears that based on the id of the false path, ProcessSplitGraphGroup loops over twice, but the false path's BB index isn't what is being used, but simply an increment of the original provided index to the call.

(https://github.com/anikau31/systemc-clang/blob/scratchllnl/plugins/hdl/HDLThread.cpp#L339)

mayagokhale commented 1 year ago

False path is length 2 but only one item is in the path vector false path, so we index off the end.