SystemC / TLM: simple uso de peq

En la programación SystemC / TLM, peq es una herramienta muy importante, sobre todo en la tubería como la simulación RTL en la escena, es esencial.
Podemos pensar en peq es que uno puede establecer la ruta de la demora tubería, retrasar una transacción establecido en la entrada a un retraso esta transacción puede ser visto desde la salida.
Usted puede obtener la misma transacción múltiple tiro a la salida del Peq.
peq ventaja es que, no importa la cantidad de empuje en la transacción de entrada, que corresponde a un tiempo de transacción, sin duda se puede ver en la salida para asegurar el proceso de retardo es correcta y no se pierda la transacción.
peq ruta de origen: ~ SystemC-2.3.1 / src / tlm_utils / peq_with_get.h, si quieres ver cómo funciona, se puede ver directamente en el código fuente, o referencia SystemC documentación oficial.
Lo siguiente da un ejemplo simple de peq. Las funciones básicas implementadas ser: a 0T empujar una transacción cuando el retardo de tubería, camino 10T; B en el tiempo de 2T empuje transacción 2 a la tubería, 3T retardo del trayecto. Los resultados de la simulación generados:
Aquí Insertar imagen Descripción
PEQ necesita principalmente en el curso de los siguientes:

  1. Puesto que solamente una peq_with_get constructor, no hay parámetros con los valores predeterminados; Descripción peq_with_get ningún constructor defecto, se peq_with_get variables miembro definidos debe ser inicializado en la lista de inicialización. Si no inicializado pero los errores de compilación
    Aquí Insertar imagen Descripción

  2. peq debe garantizarse sin el tipo TLM :: tlm_generic_payload, puede ser cualquier tipo, los ejemplos se utilizan unsigned int. Pero tenga en cuenta que notifique el contenido no debe ser un espacio de memoria temporal, en general, hacer que apunte al espacio de memoria asignada dinámicamente es nueva. En tal caso, no en la ausencia de nuevos casos notificará directamente a una variable * t_num_1 local.

  3. Si el mismo es de transacción notifican dos veces, una vez, dos veces, será cubierta no se llega a la parte delantera.

  4. En get peq en el hilo, mientras que get_next_transaction, no se puede tener otro evento de espera, de lo contrario habrá un período de tiempo predeterminado podría llegar, pero para este subproceso objetivo todavía está esperando para otro evento, por lo que llegar a la hora trans de normalmente se retrase. Hay un retraso no puede esperar ciclo y similares.
    Por supuesto, en el caso de un uso incorrecto del ciclo de espera u otro evento de, la transacción en sí no es desechado. Por ejemplo, en este ejemplo, espera en el proceso de un curso trans del 10T, que también es el primer nº1 qué conseguir próxima transacción, la respuesta es sí. Los resultados de la simulación son:
    Aquí Insertar imagen Descripción

  5. En hilo GetPeq en, wait () espera a que el hilo correspondiente es eventos sensibles, es decir, peq.get_event (), esta wait () no debe ser omitido, de lo contrario debe en ningún otro espera hilo, conducirá el programa en un bucle infinito. Resumen de 04:00 y 05:00 es, de hilo GetPeq, hay una y sólo una de espera, que espera peq.get_event ().

  6. Debe haber sido un encuentro de una sola vez en obtener el próximo tiempo de la transacción, hasta igual a NULL. Debido a que la misma toma puede obtener de transacciones múltiples, si no llegar hasta NULL, entonces puede ser transacción perdida. Por ejemplo, utilizamos esta forma, pero la espera que pase a un uso incorrecto de la 10T, número 1 dará lugar a la pérdida. Los resultados de la simulación:
    t_get = m_test_peq.get_next_transaction ();
    if (! = NULL t_get)
    Aquí Insertar imagen Descripción

Ejemplos de la main.cpp código fuente

/*
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;
}

Publicado ocho artículos originales · ganado elogios 0 · Vistas 192

Supongo que te gusta

Origin blog.csdn.net/zgcjaxj/article/details/104877270
Recomendado
Clasificación