SystemC



  • kennt einer von euch sich mit systemc aus?

    ich möchte aus der klasse sc_int eine klasse ableiten?

    ich habe es mir so vorgestellt:

    #ifndef SC_ERRINT_H
    #define SC_ERRINT_H
    
    #include <systemc.h>
    
    template <int T> class sc_errint : public sc_int<T>
    {
    public:
    
    	sc_errint(int val):sc_int(val)
    	{}
    
        sc_errint operator * (sc_errint<T> rh)
    	{   
    		return (&(sc_int<T>)this * (sc_int<T>)rh + rand());
    	}
    };
    
    #endif
    

    der operator soll überladen werden um andere funktionen zu realisieren:

    nun aber funktionniert das ganze bei mir nicht.

    habt ihr vielleicht ne ahnung woran das liegen könnte?



  • Was genau willst du denn machen?
    this ist jedenfalls vom Typ 'sc_errint*', und das kann man nicht einfach so in sc_int<T> casten.
    Ausserdem hast du lediglich einen ctor mit int Argument, also muss folgender Ausdruck

    (&(sc_int<T>)this * (sc_int<T>)rh + rand())
    

    als int interpretiert werden können. Ob deine Basisklasse entsprechende Funktionalität bereitstellt, weiss ich nicht.
    Willst du einfach nur operator * der Basisklasse nutzen, kannst du das auch anders machen

    sc_errint operator * (const sc_errint& rh)
        {
            return sc_int<T>::operator *(rh) + rand();
        }
    

    Wie bereits erwähnt, muss die Basisklasse natürlich entsprechende Operatoren bereitstellen.

    btw:
    - es ist durchaus sinnvoller, operator * ausserhalb der Klasse zu definieren
    - achte auf const-correctness
    - gewöhn dir C Casts ab
    - deine Klasse ist schlecht designed, entweder benutzt du Layering oder non-public Vererbung



  • Danke erstmals.

    was ich genau machen will ist folgendes:

    ich habe ein programm geschrieben der sc_int zahlen multipliziert.

    nun will ich aber in meinen eingängen fehlern einbauen damit ich dann eine fehlerha´fte multiplikation dabei rauskommt (...) ich wollte eine neue klasse von der sc_int klasse ableiten, und darin den operator * überladen, der dann die multiplikation manipulieren soll..

    ich hab es mir so vorgestellt..was hälst du davon?

    danke



  • Ich kann mir zwar immer noch nicht vorstellen, was genau du machen willst (was meinst du zB mit "in meinen eingängen fehlern einbauen"?) und wofür das gut sein soll...aber egal. Ansich kannst du ja alles machen was du willst. Du solltest nur bedenken, dass bei der Multiplikation auch sc_errint Operanden vorliegen müssen, damit der entsprechende Operator ausgeführt wird.
    Vielleicht kannst du ja nochmal erklären, was operator * von sc_errint genau machen soll. Dann könnte man den sicher korrigieren.



  • also ich erkläre dir das ganze in details:

    es geht darum eine fehlertoleranz architektur in systemc zu implementieren.
    diese besteht aus mehreren ebenen.
    die erste stufe:da sind die eingänge a und b
    in der zweiten stufe: da sind n mutltipler die a und b als eingänge haben und als ausgang eine array c mit n elementen.
    in der dritten stufe folgt eine gewichtung aller ergebnisse.

    sinn der sache ist das man mit bestimmten verfahren trotz fehlerhaftem verhalten von manchen Multipliers, man am ende das richtige ergebnis erreichen kann.

    deswegen würde ich die eingänge so manipulieren, jedes mal mit einer wahrscheinlichkeit p ,dass die multiplier so zu sagen falsche ergebnisse liefern.

    ich hab es mir so überlegt..dass ich eine neue klasse von sc_int ableite, in der ich den operator * überlade.dieser soll erst die eingänge manipuliert und dann die multiplikation durchführt.



  • hatte keine von euch ein idee?

    danke



  • Du hast also einen Multiplier, der a und b als Parameter bekommt. Dass es n Multiplier gibt ist erstmal unwichtig, denn ich vermute mal, dass jeder Multiplier a und b als Parameter bekommt.
    Damit nun operator * von sc_errint aufgerufen wird, muss, wie bereits erwähnt, a und b vom Typ sc_errint sein. Falls dies nicht möglich ist, kannst du immer noch temporäre Objekte muliplizieren

    ergebnis = sc_errint<wasauchimmmer>(a) * sc_errint<wasauchimmmer>(b);
    

    Sollte sc_int keinen operator int() haben, dann brauchst du übrigens noch einen passenden sc_errint ctor.

    sc_errint(const sc_int<T>& source)
        : sc_int<T>(source)
    {
    }
    

    Ansonsten versteh ich nicht so ganz, wo genau dein Problem liegt, bzw was nicht so funktioniert wie du dir das vorstellst. 😕

    btw:
    Weil wir gerade das Thema in einem anderen Thread hatten, es ist durchaus sinnvoller, operator * ausserhalb der Klasse zu definieren.

    template <int T>
    sc_errint<T> operator *(const sc_errint<T>& lhs, const sc_errint<T>& rhs)
    {
        const sc_int<T>& l = lhs;
        const sc_int<T>& r = rhs;
        return l * r + rand();
    }
    


  • danke...

    die klasse ist bereits erfolgreich abgeleitet da musste noch ein leerer Konstrultor rein.

    nun habe ich folgendes problem:

    nachdem ich den * erfolgreich überladen habe, wird im programm das normale * benutzt also nicht das überladene. obwohl a und b vom typ sc_errint definiert sind.

    hast du vielleicht nen gedankenstoß?



  • the_one schrieb:

    nachdem ich den * erfolgreich überladen habe, wird im programm das normale * benutzt also nicht das überladene

    Das muss ja nicht zwangsläufig falsch sein, wenn zB operator * von sc_errint den operator * von sc_int aufruft. Bist du dir wirklich sicher, dass nur der operator * von sc_int aufgerufen wird? Mach mal irgendeine Ausgabe in beide Operatore, wie zB

    std::cout << "operator * von bla aufgerufen" << std::endl;
    

    oä, um wirklich sicher zu gehen.

    Ansosnten, zeig mal die Definition von a und b, und die Stelle, wo beide multipliziert werden.



  • die definition von a und b :

    sc_in< sc_errint<4> > a;
    sc_in< sc_errint<4> > b;
    sc_out< sc_errint<8> > c;

    multiplikation

    c.write(a.read() * b.read());

    habe es auch mit :

    c=a*b;

    und

    c.write(sc_errint<8>(a.read()* b.read());

    aber gibt genau dieseselben ergebnisse

    und das mal wird sicher von der sc_int klasse übernommen nicht von der sc_errint

    🙄 🙄



  • the_one schrieb:

    habe es auch mit :

    c=a*b;

    Dass das nicht funktioniert ist klar. a und b sind vom Typ sc_in, dann musst du schon schaun, was operator * von sc_in macht. Falls es überhaupt einen gibt.

    the_one schrieb:

    c.write(a.read() * b.read());

    OK, in dem Fall muss man den Rückgabetyp von read() kennen. 🙂



  • sc_in und sc_out stehen jeweils für eingang und ausgang..das sagt nichts über den typen aus..

    mit c.write(a.read() * b.read()) klapt es leider nicht 🙄 🙄



  • the_one schrieb:

    sc_in und sc_out stehen jeweils für eingang und ausgang..das sagt nichts über den typen aus..

    Doch, das tut es. a und b sind nunmal vom Typ sc_in<...>, dh heisst, du musst bei dessen operator * nachschaun was passiert, wenn du a * b rechnest.

    the_one schrieb:

    mit c.write(a.read() * b.read()) klapt es leider nicht 🙄 🙄

    Nichts neues. Du solltest dir eigentlich den Rückgabetyp von read() anschaun, um den verwendeten Operator zu spezifizieren.

    Offensichtlich fehlen dir einige C++ Grundkenntnisse. Vielleicht wäre es besser, wenn du dir erstmal ein gutes Tutorial über Operatoren anschaust, bevor du mit SystemC weitermachst.



  • endlich geschafft..

    also jetzt wird der neue operator angenommen und angewendet..
    die überladung muss so heissen:

    template <int T> 
    sc_errint<2*T> operator *(const sc_errint<T>& lhs, const sc_errint<T>& rhs) 
    { 
        const sc_int<T>& l = lhs; 
        const sc_int<T>& r = rhs; 
        return l * r + rand(); 
    }
    

    und die konstrukturen so :

    sc_errint() : sc_int<T>() {} 
    sc_errint(const sc_int<T>& source):sc_int<T>(source) {}
    

    jetzt würde ich innerhalb dieses operator einzelne bits abändern zum beispiel
    aus 1001 * 1101 würde ich 1011*1001 haben..die bitänderung soll zufällig erfolgen..

    hast du ne idee?



  • the_one schrieb:

    jetzt würde ich innerhalb dieses operator einzelne bits abändern zum beispiel
    aus 1001 * 1101 würde ich 1011*1001 haben..die bitänderung soll zufällig erfolgen..

    hast du ne idee?

    Dafür kannst du die bitweise arbeitenden Operatoren benutzen ➡ << >> & | ^
    Diese musst du dann halt nur noch mit einer gewissen Strategie auf den Wert des linken und rechten Operanden loslassen.
    Seh ich das richtig, dass du zB die Reihenfolge der Bits invertieren möchtest? Leider gibt es dafür keine native Möglichkeit. Aber sowas kann man mit Hilfe einer Schleife relativ einfach selbst machen.


Anmelden zum Antworten