UVM TLM FIFO通信 示例

示例:

具体概念详见[UVM 事务级建模TLM 单向/多向通信 端口 FIFO通信](https://blog.csdn.net/qq_40456702/article/details/126682331?spm=1001.2014.3001.5501)

在这里插入图片描述

component A 每隔 50ns 往 tlm_fifo 写入一个 transaction,component B 每隔 100ns 从 tlm_fifo 读出一个 transaction

1. 定义 transaction

// Packet (transaction)继承自uvm_object,其在组件之间传输

class Packet extends uvm_object;
	randbit[7:0] addr;
    randbit[7:0] data;
 
    `uvm_object_utils_begin(Packet)
    `uvm_field_int(addr, UVM_ALL_ON)
    `uvm_field_int(data, UVM_ALL_ON)
    `uvm_object_utils_end
 
    function new(string name = "Packet");
    	super.new(name);
    endfunction
endclass

2. 定义 component A

// 创建component A,定义 put_port,实现 transaction 的生成、约束和发送

class componentA extendsuvm_component;
	`uvm_component_utils (componentA)
 
    uvm_blocking_put_port #(Packet) m_put_port;
    int m_num_tx = 2;
 
    function new (string name = "componentA", uvm_component parent= null);
    	super.new (name, parent);
    endfunction
 
    virtual function void build_phase(uvm_phase phase);
    	super.build_phase(phase);
    	m_put_port = new ("m_put_port", this);
    endfunction
 
    virtual task run_phase(uvm_phase phase);
    	phase.raise_objection(this);
    	
    	repeat (m_num_tx) begin  //  component A每隔 50个时钟周期, 往 tlm_fifo 写入一个 transaction,写两次。
	        Packet pkt = Packet::type_id::create ("pkt");
	        assert(pkt.randomize ());
	        
	    	#50;   
	        //Print the packet to be displayed in log
	        `uvm_info ("COMPA", "Packetsent to CompB", UVM_LOW)
	         pkt.print (uvm_default_line_printer);
	 
	         //Call the TLM put() method of put_port class and pass packet as argument
	         m_put_port.put(pkt);
    	end
    	phase.drop_objection(this);
  	endtask
endclass

3. 定义 component B

// 创建component B,定义get_port,实现transaction的接收
// 可以看出,uvm_tlm_fifo的两端都是export,都是put()和get()的实现端,而不是发起端

class componentB extendsuvm_component;
	`uvm_component_utils (componentB)
 
  	//Create a get_port to request for data from componentA
  	uvm_blocking_get_port #(Packet) m_get_port;
  	int m_num_tx = 2;
 
  	function new (string name, uvm_component parent);
    	super.new (name, parent);
  	endfunction
 
  	virtual function void build_phase(uvm_phase phase);
     	super.build_phase(phase);
     	m_get_port = new ("m_get_port", this);
  	endfunction
 
  	virtual task run_phase(uvm_phase phase);
    	Packet pkt;
    	phase.raise_objection(this);
    	
    	repeat (m_num_tx) begin  // component B 每隔 100个时钟周期 从 tlm_fifo 读出一个 transaction,写两次
	      	#100;
	        m_get_port.get(pkt);
	        `uvm_info ("COMPB", "ComponentAjust gave me the packet", UVM_LOW)
	       	pkt.print (uvm_default_line_printer);
     	end
    	phase.drop_objection(this);
  	endtask
endclass

4. 在上层 env 定义 uvm_tlm_fifo

// 在更高的测试平台层次中定义uvm_tlm_fifo
// 连接 comp A 的 put_port 和 tlm_fifo 的 put_export,以及 comp B 的 get_port 和 tlm_fifo 的 get_export

class my_test extendsuvm_env;
 	`uvm_component_utils (my_test)
 
  	componentA compA;
  	componentB compB;
 
 	int m_num_tx;
 
  	//Create the UVM TLM Fifo that can accept simple_packet
  	uvm_tlm_fifo #(Packet)   m_tlm_fifo;
 
  	function new (string name = "my_test", uvm_component parent = null);
     	super.new (name, parent);
  	endfunction
 
  	virtual function void build_phase(uvm_phase phase);
     	super.build_phase(phase);
     	//Create an object of both components
     	compA = componentA::type_id::create ("compA", this);
     	compB = componentB::type_id::create ("compB", this);
   	 	std::randomize(m_num_tx) with {m_num_tx inside {[4:10]}; };
    	compA.m_num_tx = m_num_tx;
    	compB.m_num_tx = m_num_tx;
 
     	// 创建tlm fifo 深度为2
     	m_tlm_fifo = new ("uvm_tlm_fifo", this, 2);
  	endfunction
 
  	//Connect the ports to the export of FIFO.
  	virtual function void connect_phase(uvm_phase phase);
    	compA.m_put_port.connect(m_tlm_fifo.put_export);
    	compB.m_get_port.connect(m_tlm_fifo.get_export);
  	endfunction
 
 	// 查询fifo是否为满
  	virtual task run_phase(uvm_phase phase);
     	forever begin
       	#10;
       	if(m_tlm_fifo.is_full ())
         	`uvm_info ("UVM_TLM_FIFO", "Fifo isnow FULL !", UVM_MEDIUM)         
     	end
  	endtask
endclass

仿真结果

# UVM_INFO tb_classes/componentA.sv(33) @50: uvm_test_top.compA [COMPA] Packet sent to CompB
# pkt: (Packet@543) { addr: 'h10  data: 'hcc }
# UVM_INFO tb_classes/componentB.sv(26) @100: uvm_test_top.compB [COMPB] ComponentA just gave me the packet
# pkt: (Packet@543) { addr: 'h10  data: 'hcc }
# UVM_INFO tb_classes/componentA.sv(33) @100: uvm_test_top.compA [COMPA] Packet sent to CompB
# pkt: (Packet@544) { addr: 'h3e  data: 'h92 }
# UVM_INFO tb_classes/componentA.sv(33) @150: uvm_test_top.compA [COMPA] Packet sent to CompB
# pkt: (Packet@545) { addr: 'hde  data: 'h65 }
# UVM_INFO tb_classes/my_test.sv(40) @ 150:uvm_test_top [UVM_TLM_FIFO] Fifo is now FULL !
# UVM_INFO tb_classes/my_test.sv(40) @ 160:uvm_test_top [UVM_TLM_FIFO] Fifo is now FULL !
# UVM_INFO tb_classes/my_test.sv(40) @ 170:uvm_test_top [UVM_TLM_FIFO] Fifo is now FULL !
# UVM_INFO tb_classes/my_test.sv(40) @ 180:uvm_test_top [UVM_TLM_FIFO] Fifo is now FULL !
# UVM_INFO tb_classes/my_test.sv(40) @ 190:uvm_test_top [UVM_TLM_FIFO] Fifo is now FULL !
# UVM_INFO tb_classes/componentB.sv(26) @200: uvm_test_top.compB [COMPB] ComponentA just gave me the packet
# pkt: (Packet@544) { addr: 'h3e  data: 'h92 }

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SV小项目-异步FIFO是一个简单的项目,旨在让学生理解FIFO缓存的原理和实现方式。 FIFO缓存是一种常用的数据存储方式,可以用于解决数据传输时的不匹配问题。在异步FIFO中,数据的写入和读取是异步的,意味着数据可以在任何时候写入或读取。这种异步的方式可以增加FIFO的灵活性,并且允许数据的写入和读取在不同的时钟域上应用。 这个小项目的主要目标是实现一个基于Verilog的异步FIFO模块,包括以下功能: 1. 内部缓存的储存和检索 2. 空和满指示器的生成 3. 数据的写入和读取 对于写入操作,当FIFO未满时,它将数据存储在内部缓存中,并更新其指针以指向下一个空位置。当缓存已满时,写入操作将被忽略,并且FIFO满指示器将被设置为高电平。同样,读取操作从内部缓存中检索数据,并将其指针更新以指向下一个位置。当缓存为空时,读操作将被忽略,并且FIFO空指示器将被设置为高电平。 在设计过程中,需要考虑解决的问题包括时序和异步信号的同步。时序问题可以通过FIFO指针和状态机解决,而异步信号可以通过信号同步器进行同步。此外,还需要考虑FIFO的读写顺序和存储器的尺寸,并确保FIFO模块的有效性和可靠性。 总之,通过实现SV异步FIFO项目,学生可以加深对FIFO缓存的理解,并学习基于Verilog的设计和实现。此外,学生还可以通过在项目中遇到的挑战来提高他们的编程和设计技能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值