SystemC / TLM: einfache Nutzung von peq

In SystemC / TLM - Programmierung, ist peq ein sehr wichtiges Instrument, vor allem in der Pipeline wie RTL - Simulation in der Szene, ist von wesentlicher Bedeutung.
Wir können uns PEQ ist , dass man den Weg der Pipelineverzögerung einstellen kann, um eine Transaktion verzögern am Eingang zu einer Verzögerung dieser Transaktion einrichten kann von dem Ausgang zu sehen ist.
Sie können die gleiche Schuss mehrere Transaktion am Ausgang des Peq bekommen.
peq Vorteil ist , dass, egal wie viel Schub am Eingang Transaktion zu einer Transaktion Zeit entspricht, sicher können Sie an der Ausfahrt sehen Sie die Verzögerungsprozess , um sicherzustellen , ist richtig und nicht verpassen Transaktion.
peq Source - Strecke: ~ SystemC-2.3.1 / src / tlm_utils / peq_with_get.h, wenn Sie sehen wollen , wie es funktioniert, können Sie direkt auf den Quellcode schauen, oder Referenz SystemC offizielle Dokumentation.
Im Folgenden finden Sie ein einfaches Beispiel für peq. Die Grundfunktionen realisiert werden: A 0T drücken , um eine Transaktion , wenn die Pipeline, Wegverzögerung 10T; B zum Zeitpunkt 2T Push Transaktion 2 an die Rohrleitung, Wegverzögerung 3T. Die resultierenden Simulationsergebnisse:
Hier hat Bild einfügen Beschreibung
PEQ muss vor allem im Laufe der folgenden:

  1. Da nur ein Konstruktor peq_with_get gibt es keine Parameter mit Standardwerten, Beschreibung keine Standardkonstruktors peq_with_get, peq_with_get es Membervariablen definiert wird, muss in der Initialisierungsliste initialisiert werden. Wenn nicht initialisiert aber Kompilierungsfehlern
    Hier hat Bild einfügen Beschreibung

  2. peq muss ohne den Typ TLM :: tlm_generic_payload garantiert werden, kann jede Art sein, sind Beispiele unsigned int verwendet. Aber beachten Sie, dass die Inhalte benachrichtigen darf keine temporäre Speicherplatz in der Regel sein, macht es zu dynamisch zugewiesenen Speicherplatz Punkt ist neu. In einem solchen Fall nicht in Abwesenheit von Neuerkrankungen benachrichtigen direkt eine lokale Variable * t_num_1.

  3. Wenn die gleiche Transaktion zweimal melden, einmal, zweimal wird, abgedeckt wird nicht an die Front bekommen.

  4. In get peq im Thread, während get_next_transaction, können Sie keinen anderen Wait Event haben, sonst wird es eine vorgegebene Zeitspanne bekommen sein könnte, aber für diesen Zweck Thread warten noch auf ein anderes Ereignis, so zu trans Zeit bekommen als normalerweise verzögert werden. Es gibt eine Verzögerung kann nicht Zyklus warten und dergleichen.
    Natürlich selbst im Falle einer falschen Verwendung des Wartezyklus oder ein anderes Ereignis der Transaktion wird nicht weggeworfen. ja zum Beispiel in diesem Beispiel Warten im Prozess eines trans Verlaufs des 10T, es ist auch das erste Nummer1 , was nächste Transaktion zu bekommen, ist die Antwort. Die Simulationsergebnisse sind:
    Hier hat Bild einfügen Beschreibung

  5. In GetPeq Gewinden in, wait () wartet auf das entsprechende Gewinde ist empfindlich Ereignisse, das heißt, peq.get_event (), diese wait () nicht verzichtet werden, da ansonsten aufgrund in keiner anderen Thread wartet, wird das Programm in eine Endlosschleife führt. Zusammenfassung von 04.00 Uhr bis 5:00 ist, in GetPeq Gewinde, gibt es eine und nur eine Wartezeit, die Warte peq.get_event ().

  6. Es muss eine get one-Zeit gewesen sein in der nächste Transaktionszeit erhalten, bis gleich NULL. Da die gleiche Einstellung kann mehrere Transaktion erhalten, wenn nicht bis NULL bekommt, dann kann es verlorene Transaktion. Zum Beispiel haben wir dieses Formular benutzen, aber das Warten geschieht nicht sachgemäßen Gebrauch der 10T, Nummer 1 führt zum Verlust führen. Die Simulationsergebnisse:
    t_get = m_test_peq.get_next_transaction ();
    if (! T_get = NULL)
    Hier hat Bild einfügen Beschreibung

Beispiele des Quellcodes main.cpp

/*
Original 2020-03-15
README:
	This is a example to teach you how to use a peq in systemC/TLM
	Assume that you want to implement such a scenario:
	 A delay 10T to a pipeline at 0T; B delay 3T to the same pipeline at 2T

execute:	
	g++ -g -Wall -lsystemc -m64 -pthread main.cpp  -L/$(your systemc path)/lib-linux64 -I/$(your systemc path)/include  -I/$(your systemc path)/src/tlm_utils -o sim

you need particular attention that  
	1. the only constructor of peq_with_get have a paramater, \
		it have no default constructor,\
		 so you must initialize it use initialization list

		you can check the constructor at ~systemc-2.3.1/src/tlm_utils/peq_with_get.h 
		   peq_with_get(const char* name) : sc_core::sc_object(name)

	2. for other points, can check my csdn blog
*/


#include <iostream>

#include "systemc.h"
#include "tlm_utils/peq_with_get.h"

using namespace std;

class TestPlatform
: public sc_module
{
	public:
		SC_HAS_PROCESS(TestPlatform);

		TestPlatform(const sc_module_name&    name)
        : sc_module(name)
		, m_period (sc_time(1000,SC_PS))
		, m_test_peq("test_peq")
		{
			SC_THREAD(PushPeq_1);
			SC_THREAD(PushPeq_2);

			SC_THREAD(GetPeq);
    		sensitive<<m_test_peq.get_event();//sensitive event list
		};

	public:
		void PushPeq_1();
		void PushPeq_2();
		void GetPeq();

		~TestPlatform()
		{;}
		
	public:
		sc_time 			m_period;
		tlm_utils::peq_with_get<unsigned int >   
							m_test_peq;
};

void TestPlatform::PushPeq_1()
{
	unsigned int * t_num_1 = new  unsigned int ;
	* t_num_1 =  100;
	
	// the transaction that peq will notify can't be a temporary memory space
	m_test_peq.notify(*t_num_1 , 10 * m_period );
	cout<<"["<<sc_time_stamp()
		<<"] notify number 1 to peq, notify cycle = 10"
		<<endl;
}

void TestPlatform::PushPeq_2()
{
	wait(2* m_period);
	unsigned int * t_num_2 = new  unsigned int ;
	* t_num_2 =  200;
	
	m_test_peq.notify(*t_num_2 , 3 * m_period );
	cout<<"["<<sc_time_stamp()
		<<"] notify number 2 to peq, notify cycle = 3"
		<<endl;
}

void TestPlatform::GetPeq()
{
    unsigned int * t_get = NULL;
    while(1)
    {
        wait(); //wait sensitive event list

		//here must get next transaction entil t_get is NULL
        while((t_get = m_test_peq.get_next_transaction()) != NULL)
        {
			cout<<"["<<sc_time_stamp()
				<<"] get number "
				<< * t_get
				<<endl;

			delete t_get; //dynamic memory space, delete when no use
			t_get = NULL;

			//in this block, must can't wait any event or cycle delay
			// if not, the time of transaction obtained will not accurate
			// wait(10 * m_period);	
		}
	}
}

/*
//this is an error using example
void TestPlatform::GetPeq()
{
    unsigned int * t_get = NULL;
    while(1)
    {
        wait(); 
		//this is an error using example
		// get_next_transaction not until NULL & wait other cycle 
		// will lead to number 1 missing
        t_get = m_test_peq.get_next_transaction();
		if(t_get != NULL)
        {
			cout<<"["<<sc_time_stamp()
				<<"] get number "
				<< * t_get
				<<endl;

			delete t_get; 
			t_get = NULL;

			wait(10 * m_period);	
		}
	}
}
*/


int sc_main(int argc, char** argv)
{
    TestPlatform *    m_platform;
    m_platform = new  TestPlatform("TestPlatform");
    sc_start(1,SC_US);
	return 0;
}

Veröffentlicht acht Originalartikel · erntete Lob 0 · Aufrufe 192

Ich denke du magst

Origin blog.csdn.net/zgcjaxj/article/details/104877270
Empfohlen
Rangfolge