Introduction to UVM and advanced learning pen 11 - TLM communication

Posted by Maugrim_The_Reaper on Wed, 26 Jan 2022 15:04:01 +0100

What is TLM

  • In the chip development process, system prototype and chip verification play a key role in promoting the project.
  • The system prototype usually simulates the hardware behavior through the hardware function description document, and the behavior requirements are different from the RTL model. The system prototype can provide a model that is accurate to the hardware bit level, accessed according to the address segment and does not depend on the clock cycle. The model is usually based on system C language; Each module in the system prototype can realize data packet transmission in a loose time range through TLM.
  • Chip verification is to build a verification platform through verification language and methodology after the preliminary establishment of RTL model. The characteristic of the platform is that the overall verification environment is based on object-oriented development, the communication between components is based on TLM, and the TLM Abstract transaction needs to be degraded to the signal level based on clock between driver and hardware interface.
  • TLM communication mode is used in system prototype stage and chip verification stage. The former is to realize the data communication between hardware prototypes faster, and the latter is to realize the data communication between verification components faster.
  • Simulation speed is the biggest contribution of TLM to the project progress, and the transactions in TLM transmission can ensure sufficient amount of information and accuracy.
  • TLM is not the product of a language, but exists as a standard to improve the abstraction level of data transmission.
  • High abstraction level data communication can be used to represent the hardware communication data within a loose time span. By packaging the data in the low particle hardware cycle into one big data, it is very conducive to the simulation speed of the overall environment.
  • TLM is used more and more widely, including in the co simulation framework of emulator and hardware simulator. It is also recommended to use this method to reduce the communication frequency between mixed environments in order to improve the overall operation efficiency.
  • TLM is a transaction based communication mode, which is usually used as the communication mode between modules in high-level abstract languages such as SystemC or SV/UVM.
  • TLM successfully separates the computation within the module and the communication between modules in terms of time span.
  • In the abstract language modeling system, each module is implemented through a series of parallel processes, and the correct behavior is simulated through communication and calculation.
  • If you want to improve the simulation performance of the system prototype, you need to consider the operation optimization of the modeling itself and the communication optimization between the models:
    • The former needs to rely on the experience of developers and performance analysis tools to gradually optimize the model.
    • The latter can reduce the resource loss caused by synchronization between different processes by reducing the communication frequency and increasing the content volume.
    • TLM is an abstract communication method proposed from the perspective of communication optimization.

Basic concepts

  • TLM communication requires two communication objects, which are called initiator and target respectively; The distinguishing method is that initiator - initiates the communication request, and target - the responder who initiates the communication.
  • The communication initiator does not represent the flow starting point of the Transaction, that is, the data does not necessarily flow from the initiator to the target, or it may flow from the target to the initiator.
  • Therefore, according to the flow direction of Transaction, objects can be divided into producer and consumer. Where data is generated, it belongs to producer, and where data flows, it belongs to consumer.
  • The relationship between initiator and target is not fixed with that between producer and consumer.
  • After having the object of two parameter communication, you need to implement the TLM communication method on the target side, so that the initiator can call the target communication method as the initiator in the future to realize data transmission.
  • After target implements the necessary communication methods, it is also necessary to connect the two objects. This requires creating TLM ports in the two objects, and then connecting the two objects at a higher level.

classification

TLM communication steps can be divided into:

  • Distinguish initiator and target, producer and consumer;
  • Implement TLM communication method in target;
  • Create TLM ports in two objects;
  • Connect the ports of two objects at a higher level.

In terms of data flow direction, the transmission direction can be divided into uni direction and Bi direction:

  • One way transmission: the initiator initiates the request transaction.
  • Bidirectional transmission: the initiator initiates the request transaction and transmits it to the target. After digesting the request transaction, the target initiates the response transaction and then returns it to the initiator.

Ports can be divided into:

  • Port: often used as the initiator of the initiator. The initiator can access the TLM communication method of the target by virtue of port.
  • export: the port used as the intermediate layer between initiator and target.
  • imp: it can only receive the end of the request as the target. It cannot be used as the port of the intermediate level, so the connection of imp cannot be extended again.

If the transmission direction and port type are combined, an inheritance tree of TLM ports is formed. TLM ports can be divided into six categories:

  • uvm_UNDIR_port #(trans_t)
  • uvm_UNDIR_export #(trans_t)
  • uvm_UNDIR_imp #(trans_t,imp_parent_t)
  • uvm_BIDIR_port #(req_trans_t,rsp_trans_t)
  • uvm_BIDIR_export #(req_trans_t,rsp_trans_t)
  • uvm_BIDIR_imp #(req_trans_t,imp_parent_t)

Use of ports

  • For one-way ports, if you declare port and export as request initiators, you need to specify transaction type parameters; To declare imp as the request receiver, you need to specify not only the transaction type, but also the component type.
  • For two-way ports, the specified parameters need to consider the factors of two-way transmission. The transmission type transaction is divided into request transaction type and response transaction type.

The general method of TLM port connection is obtained from the corresponding connection relationship:

  • Instantiate port on the initiator side, export on the middle level, and imp on the target side.
  • Multiple ports can connect to the same export or import, but a single port or export cannot connect to multiple imps.
  • port should be the starting point of request, imp should be the end point of request, and the middle can pass through multiple levels. Based on the consideration of self closing of unit components, export is declared at the middle level of crossing, and then the data path is realized through hierarchical connection.
  • Port can be connected to port, export or import. Export can be connected to export or import. imp can only be used as the end point of data transmission, and the connection cannot be extended.
class request extends uvm_transaction;  //REQ
	byte cmd;
	int addr;
	int req;
endclass
class response extends uvm_transaction;  //RSP
	byte cmd;
	int addr;
	int rsp;
	int status;
endclass

class comp1 extends uvm_agent;
	uvm_blocking_get_port #(request) bg_port;
	`uvm_component_utils(comp1)
	...
endclass
class comp2 extends uvm_agent;
	uvm_blocking_get_port #(request) bg_port;
	uvm_noblocking_put_imp #(request, comp2) nbp_imp;
	`uvm_component_utils(comp2)
	...
	function bit try_put(request req);
	function bit can_put();
endclass
class comp3 extends uvm_agent;
	uvm_blocking_transport_port #(request, response) bt_port;
	`uvm_component_utils(comp3)
	...
endclass
class comp4 extends uvm_agent;
	uvm_blocking_get_imp #(request, comp4) bg_imp;
	uvm_noblocking_put_port #(request) nbp_port;
	`uvm_component_utils(comp4)
	...
	task get(output request req);
endclass
class comp5 extends uvm_agent;
	uvm_blocking_transport_imp #(request ,response, comp5) bt_imp;
	`uvm_component_utils(comp5)
	...
	task transport(request req, output response rsp);
endclass

class agent1 extends uvm_agent;
	uvm_blocking_get_port #(request) bg_port;
	uvm_noblocking_put_export #(request) nbp_exp;
	uvm_blocking_transport_port #(request, response) bt_port;
	comp1 c1;
	comp2 c2;
	comp3 c3;
	`uvm_component_utils(agent1)
	...
	function void build_phase(uvm_phase phase);
		super.build_phase(phase);
		c1 = comp1::type_id::create("c1", this);
		c2 = comp2::type_id::create("c2", this);
		c3 = comp3::type_id::create("c3", this);
	endfunction
	function void connect_phase(uvm_phase phase);
		super.connect_phase(phase);
		c1.bg_port.connect(this.bg_port);		//The left side of connect can be initiator and export 	, On the right is target	
		c2.bg_port.connect(this.bg_port);
		this.nbp_exp.connect(c2.nbp_imp);		//The connection direction is from agent export to c2 import
		c3.bt_port.connect(this.bt_port);
	endfunction
endclass

class env1 extends uvm_env;
	agent1 a1;
	comp4 c4;
	comp5 c5;
	`uvm_component_utils(env1)
	...
	function void build_phase(uvm_phase phase);
		super.build_phase(phase);
		a1 = agent1::type_id::create("a1", this);
		c4 = comp4::type_id::create("c4", this);
		c5 = comp5::type_id::create("c5", this);
	endfunction
	function void connect_phase(uvm_phase phase);
		super.connect_phase(phase);
		a1.bg_port.connect(c4.bg_imp);
		c4.nbp_port.connect(a1.nbp_exp);
		a1.bt_port.connect(c5.bt_imp);
	endfunction
endclass

From the code, we can get the general steps of establishing TLM communication:

  • Define the data types in TLM transmission. The request class and response class are defined above.
  • Declare and create TLM port objects in component s of each level.
  • The connection between ports is completed through the connect() function.
  • In the imp port class, you need to implement the callable methods provided to the initiator. For example, there is a UVM in Comp2_ noblocking_ put_ imp #(request, comp2) nbp_ Imp, so the method try is required_ Put () and can_put(), and there is a UVM in comp4_ blocking_ get_ imp #(request, comp4) bg_ Imp, the method get() needs to be implemented.
  • Note that the corresponding method must be implemented in the imp port class, otherwise the port cannot realize data transmission even if it is connected.