• 【APB协议 & UVM_Sequencer & Driver & Monitor_2024.03.04】


    apb协议

    写时序

    地址、写信号、PSEL、写数据信号同时发生变化,即传输的第一个时钟被称为SETUP周期。在下个时钟上升沿,PENABLE信号拉高,表示ENABLE周期,在该周期内,数据、地址以及控制信号都必须保持有效。整个写传输在这个周期结束时完成:
    在这里插入图片描述

    读时序

    地址、写信号、PSEL信号同时发生变化,在下个时钟上升沿,PENABLE信号拉高,从机必须在ENABLE周期内提供读数据:
    在这里插入图片描述

    Sequencer

    充当激励环节的路由器作用,管理sequence,也传递数据,仲裁某一时刻传递哪个sequence的数据

    • uvm_sequencer#(REQ,RSP)
      REQ:request;RSP:response//一般相同
    • default_sequence
      决定接数据的类型
    • seq_item_export
      决定送数据的driver

    sequencer的实现

    class apb_sequencer extends uvm_sequencer #(apb_trans);
    	`uvm_component_utils(apb_sequencer);
    	function new(string name,uvm_component parent);
    		super.new(name,parent);
    	endfunction
    endclass
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    简便方法(不建议使用)typedef uvm_sequencer #(apb_trans) apb_sequencer;
    
    • 1
    • 2

    virtual sequencer

    • 不同的sequence需要不同的sequencer
    • 控制其他的sequencer
    • 不和任何driver相连
    • 本身不处理item

    实现与sequencer相同,其中可以定义子sequencer

    Driver

    driver和monitor都是数据转换类型,但方向相反

    driver的方法:
    get_next_item(阻塞)
    try_next_item(不阻塞)
    item_done(不阻塞)
    
    • 1
    • 2
    • 3
    • 4
    driver的使用
    uvm_driver(REQ,REP)
    seq_item_port.get_next_item(req);//get上述括号内传来的句柄
    
    • 1
    • 2
    • 3

    在这里插入图片描述

    driver的实现

    class apb_driver extends uvm_driver #(apb_trans);
    	`uvm_component_utils(apb_driver)
    	
    	//定义虚接口
    	virtual apb_interface vif;
    	
    	function new(string name,uvm_component parent);
    		super.new(name,parent);
    	endfunction
    	
    	//config_db连接虚接口
    	function void connect_phase(uvm_phase phase);
    		super.connect_phase(phase);
    		if(!uvm_config_db #(virtual apb_interface)::get(this,"","vif",vif);
    			`uvm_fatal("NOvif","NOvif for apb_driver");
    		end
    	endfunction
    	
    	task run_phase(uvm_phase phase);
    		super.run_phase(phase);
    		vif.paddr<=0;
    		vif.pwdata<=0;
    		vif.pwrite<=0;
    		vif.psel<=0;
    		vif.penable<=0;
    		tx_driver();
    	endtask
    	
    	//从seq_item_port获取transaction
    	task tx_driver();
    		forever begin
    			seq_item_port.get_next_item(req);
    			send(req);
    			seq_item_port.item_done();
    		end
    	endtask
    	
    	//给vif传送transaction
    	task send(apb_trans tr);
    		case(tr.dir)
    			apb_trans::RD:begin
    				@(posedge vif.clk);
    				vif.paddr<=tr.addr;
    				vif.pwrite<=0;
    				vif.psel<=1;
    				@(posedge vif.clk);
    				vif.penable<=1;
    				@(posedge vif.clk);
    				tr.data=vif.prdata;
    				vif.psel<=0;
    				vif.penable<=0;
    			end
    			apb_trans::WR:begin
    				@(posedge vif.clk);
    				vif.paddr<=tr.addr;
    				vif.pwdata<=tr.data;
    				vif.psel<=1;
    				vif.pwrite<=1;
    				@(posedge vif.clk);
    				vif.penable<=1;
    				@(posedge vif.clk);
    				tr.data=vif.prdata;
    				vif.psel<=0;
    				vif.penable<=0;
    			end
    		endcase
    endclass
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67

    Monitor

    源码中没有定义port

    monitor不用像driver一样按时序操作的原因:
    driver:transaction→DUT,DUT时序要求正确
    monitor:DUT→transaction,验证没有时序的概念,只关注行为
    
    • 1
    • 2
    • 3

    在这里插入图片描述

    monitor的实现

    class apb_monitor extends uvm_monitor;
    	`uvm_component_utils(apb_moitor);
    	
    	//定义虚接口
    	virtual apb_interface vif;
    	//利用uvm_analysis_port创建apb_mon_port
    	uvm_analysis_port #(apb_trans) apb_mon_port;
    	
    	function new(string name,uvm_component parent);
    		super.new(name,parent);
    	endfunction
    	
    	config_db连接虚接口,new apb_mon_port
    	function void build_phase(uvm_phase phase);
    		super.build_phase(phase);
    		if(!uvm_config_db #(virtual apb_interface)::get(this,"","vif",vif);
    			`uvm_fatal("NOvif","NOvif for apb_monitor");
    		end
    		apb_mon_port=new("apb_mon_port",this);
    	endfunction
    	
    	//从vif获取transaction,要create transaction,写入apb_mon_port中,base_test中会与scoreboard的uvm_analysis_imp连接
    	task run_phase(uvm_phase phase);
    		super.run_phase(phase);
    		forever begin
    			apb_trans tr = apb_trans::type_id::create("tr",this);
    			@(posedge vif.clk);
    			if(vif.psel==1 && vif.penable==1)begin
    				tr.dir=(vif.pwrite)?apb_trans::WR:apb_trans::RD;
    				tr.addr=vif.paddr;
    				tr.data=(vif.pwrite)?vif.pwdata:vif.prdata;
    				apb_mon_port.write(tr);
    			end
    		end
    	endtask
    endclass
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
  • 相关阅读:
    UI设计中色彩运用应该注意哪些问题 优漫动游
    小程序 语音搜索功能,语音识别翻译成文本进行搜索
    快速排序(Quick sort)
    自动化API测试工具ReadyAPI新增业务历史记录功能
    Windows进程的创建与结束
    前端 diy 功能模块原来如此强大和简单,我这小白也轻松学会了【带附件】
    tcpdump使用大全
    JAVAEE框架技术之14SSM综合案例
    vue3+te项目正式开发
    zemax简单非序列光学系统
  • 原文地址:https://blog.csdn.net/xiaotong121/article/details/136454430