AHB-to-APB Bridge——04apb_tran、apb_if、apb_drv、mem、apb_mon、apb_agt

news2024/9/29 11:22:38

 

apb_if放入所有apb需要的信号,以及cb

`ifndef APB_IF_SV
`define APB_IF_SV

interface apb_if;
    logic                                    pclk;
    logic                                    prst;

    logic                                    penable;
    logic                                    psel;
    logic                                    pwrite;
    logic[31 : 0]  							 prdata;
    logic[31 : 0]   						 pwdata;
    logic[31 : 0]  							 paddr;
    logic[2:0]                               prot;
    logic[3:0]                               pstrb;
    logic                                    pready;
    logic                                    pslverr;

clocking slv_cb@(posedge pclk);
   default input #1ps output #1ps;
   input penable,psel,pwrite,pwdata,paddr,prot,pstrb;
   output prdata,pready,pslverr;
endclocking:slv_cb

clocking mon_cb@(posedge pclk);
   default input #1ps output #1ps;
   input penable,psel,pwrite,pwdata,paddr,prot,pstrb;
   input prdata,pready,pslverr;
endclocking:mon_cb

endinterface

`endif // APB_IF_SV

slv_tran的Read or Write,AHB-ram是在types文件里定义,这个在package里定义了

`ifndef APB_TRAN_SV
`define APB_TRAN_SV
    
class apb_tran extends uvm_sequence_item;

rand logic[31 : 0] pdata;
rand logic[31 : 0] paddr;
rand logic[2:0]    prot; 
rand logic[3:0]    pstrb;
rand bit           pslverr;
rand int  unsigned nready_num;//cycle number

rand pkind_type_enum  pkind_type;
//Read or Write 之前是在types文件里定义 这个在package里定义了

    `uvm_object_utils_begin(apb_tran)
        `uvm_field_int(paddr,UVM_DEFAULT)
        `uvm_field_int(pdata,UVM_DEFAULT)
        `uvm_field_int(prot,UVM_DEFAULT)
        `uvm_field_int(pstrb,UVM_DEFAULT)
        `uvm_field_int(pslverr,UVM_DEFAULT)
        `uvm_field_int(nready_num,UVM_DEFAULT)
        `uvm_field_enum(pkind_type_enum,pkind_type,UVM_DEFAULT)
    `uvm_object_utils_end

    function new (string name = "apb_tran");
        super.new(name);
    endfunction

endclass
`endif//APB_TRAN_SV

apb_drv:  使用一个mem(32,32)存放数据,传递vif(之前在agent传递并连接drv、mon);get and run要确保penable=0 psel=1时开始;在drive_one_t中根据tran中的nready_num测试没有准备好的状态;写操作放入mem;读操作从mem提出;

`ifndef APB_SLV_DRV_SV
`define APB_SLV_DRV_SV
class apb_slv_drv extends uvm_driver#(apb_tran);
 
  `uvm_component_utils(apb_slv_drv)
  virtual apb_if vif;
  apb_mem#(32,32) mem;//存放写data数据
  apb_tran 		    t;
  function new(string name = "apb_slv_drv", uvm_component parent);
      super.new(name,parent);
  endfunction

  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
	t=apb_tran::type_id::create("pkt",this);
	mem=apb_mem#(32,32)::type_id::create("apb_mem",this);
	if(!uvm_config_db#(virtual apb_if)::get(this,"","vif",vif))begin
      `uvm_fatal("NO VIF","vif is not found");//传递vif 之前是在agent传递并连接drv、mon
    end
  endfunction

  virtual task run_phase(uvm_phase phase);
    super.run_phase(phase);
	vif.slv_cb.pready  <= 1'b1;//初始化ready、slverr
    vif.slv_cb.pslverr <= 1'b0;
	fork
		get_and_drive();
	join_none
  endtask
  
  virtual task get_and_drive();
	forever begin
	  @(vif.slv_cb)
	  if(!vif.slv_cb.penable & vif.slv_cb.psel)begin//sel阶段
		seq_item_port.get_next_item(t);
		`uvm_info(get_type_name(),"sequencer got next item",UVM_HIGH)
		drive_one_t(t);
        seq_item_port.item_done(t);
        `uvm_info(get_type_name(), "sequencer item_done_triggered", UVM_HIGH)
	  end
	end 
  endtask:get_and_drive
  
  virtual task drive_one_t(apb_tran t);
	int nready_cnt;
	nready_cnt = t.nready_num;//测试nready
	while(nready_cnt != 0)begin
		vif.slv_cb.pready <= 1'b0;
		nready_cnt--;
		@(vif.slv_cb);
	end
    vif.slv_cb.pready <= 1'b1;
    vif.slv_cb.pslverr<= t.pslverr;

    if(vif.slv_cb.pwrite)
      do_write(t);
    else
      do_read(t);
  endtask
  
  virtual task do_write(apb_tran t);//写操作放入mem
    if(!t.pslverr)begin
      mem.put_data(vif.slv_cb.paddr,vif.slv_cb.pwdata);
    end
  endtask

  virtual task do_read(apb_tran t);//读操作从mem提出
   if(!t.pslverr)begin
      vif.slv_cb.prdata <= mem.get_data(vif.slv_cb.paddr);
    end
    else begin
      vif.slv_cb.prdata <= t.pdata;
    end
  endtask

endclass

`endif//APB_SLV_DRV_SV


mem:写入put进去  读出时判断是否存在写入过的地址

class apb_mem#(DW=32,AW=32) extends uvm_object;

  `uvm_object_param_utils(apb_mem)
  logic [DW-1:0] mem[int];

  function new(string name = "apb_mem");
    super.new(name);
  endfunction

  task put_data(int addr,logic[DW-1:0] data);
    this.mem[addr] = data;
    `uvm_info(get_full_name(), $sformatf("APB-Memory Write.Address:%0h. Data:%0h.",addr,data),UVM_MEDIUM)
  endtask

  function logic[DW-1:0] get_data(int addr);
    if(this.mem.exists(addr))begin//判断mem中是否有这个地址写入过
      get_data = this.mem[addr];
      `uvm_info(get_full_name(), $sformatf("APB-Memory pre-defined Read.Address:%0h. Data:%0h.",addr,get_data),UVM_MEDIUM)
    end
    else begin
      get_data = $urandom_range(32'hffff_ffff);
      `uvm_info(get_full_name(), $sformatf("APB-Memory un-defined Read.Address:%0h. Data:%0h.",addr,get_data),UVM_MEDIUM)
    end
  endfunction
endclass

mon:

`ifndef APB_SLV_MON
`define APB_SLV_MON

class apb_slv_mon extends uvm_monitor;
  `uvm_component_utils(apb_slv_mon)
  uvm_analysis_port #(apb_tran) item_port;
  virtual apb_if vif;


  function new(string name = "apb_slv_mon", uvm_component parent = null);
    super.new(name, parent);
  endfunction

  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
	item_port = new("item_observed_port", this);
	 if(!uvm_config_db#(virtual apb_if)::get(this,"","vif",vif))begin
      `uvm_fatal("No vif","vif is not found")
    end
  endfunction

  task run_phase(uvm_phase phase);
    super.run_phase(phase);
	apb_tran t;
	while(1)begin
      @(vif.mon_cb);
      if(vif.mon_cb.penable & vif.mon_cb.pready &vif.mon_cb.psel & vif.mon_cb.presetn)begin
        t = apb_tran::type_id::create("t",this);
        t.paddr = vif.mon_cb.paddr;
        t.prot = vif.mon_cb.prot;
        t.pslverr = vif.mon_cb.pslverr;
        t.pkind_type = vif.mon_cb.pwrite ? WRITE:READ;
        t.pdata = vif.mon_cb.pwrite ? vif.mon_cb.pwdata : vif.mon_cb.prdata;
        item_port.write(t);
      end
    end
  endtask
endclass

`endif // APB_SLV_MON

apb_agt: 如果is_active为1例化sqr、drv,否则只例化mon

                方便芯片集成以后只接收别的模块来的信号,不需要自己发送激励

`ifndef APB_SLV_AGT_SV
`define APB_SLV_AGT_SV

class apb_slv_agt extends uvm_agent;

  apb_slv_drv drv;
  apb_slv_mon mon;
  apb_slv_sqr sqr;

  virtual apb_if vif;

  `uvm_component_utils(apb_slv_agt)

  function new(string name = "apb_slv_agt", uvm_component parent = null);
    super.new(name, parent);
  endfunction

  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    if(!uvm_config_db#(virtual apb_if)::get(this,"","vif",vif))begin
        `uvm_fatal("GETVIF","cannot get vif handle from config DB")
    end

    mon = apb_slv_mon::type_id::create("mon",this);
	uvm_config_db#(virtual apb_if)::set(this,"mon_i","vif",vif);
	
    void'(uvm_config_db#(uvm_active_passive_enum)::get(this,"","is_active",is_active));	
	if(is_active == UVM_ACTIVE)begin
      sqr_i = apb_slv_sqr::type_id::create("sqr_i",this);
      drv_i = apb_slv_drv::type_id::create("drv_i",this);
      uvm_config_db#(virtual apb_if)::set(this,"drv_i","vif",vif);
    end
  endfunction

  function void connect_phase(uvm_phase phase);
    super.connect_phase(phase);
    if(is_active == UVM_ACTIVE)begin
      drv_i.seq_item_port.connect(sqr_i.seq_item_export);
    end
  endfunction

  task run_phase(uvm_phase phase);
    super.run_phase(phase);
  endtask

endclass


`endif // APB_SLV_AGT_SV

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/545805.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++的stack和queue

stack和queue 1.stackstack的模拟实现 2.queuequeue的模拟实现 3.容器适配器3.1. 什么是容器适配器3.2. STL标准库中stack和queue的底层结构3.3. deque的简单介绍3.3.1. deque原理介绍3.3.2. deque的缺陷3.3.3. 为什么选择deque作为stack和queue的底层默认容器 1.stack stack的…

深度学习-第T7周——咖啡豆识别

深度学习-第T7周——咖啡豆识别 深度学习-第T7周——咖啡豆识别一、前言二、我的环境三、前期工作1、导入数据集2、查看图片数目 四、数据预处理1、 加载数据1、设置图片格式2、划分训练集3、划分验证集4、查看标签 2、数据可视化3、检查数据4、配置数据集 五、搭建CNN网络六、…

Vue3+TS知识点补充

一、关于Ref 1.shallowRef() shallowRef 是 Vue 3 中新引入的响应式数据类型之一&#xff0c;它与 ref 类型非常相似&#xff0c;但是有一些不同点。 不同的是&#xff0c;shallowRef 只会对其包装的对象进行浅层次的响应式处理&#xff0c;即如果这个对象的子属性发生改变&…

软件测试——黑盒测试

1.测试概述 1.1综述 本测试报告为计算机程序能力在线测评系统的黑盒测试&#xff0c;黑盒测试可以在不知道程序内部结构和代码的情况下进行&#xff0c;用来测试软件功能是否符合用户需求&#xff0c;是否达到用户预期目标&#xff0c;是否拥有较好的人机交互体验。 图1.1 黑…

media设备节点初始化与Video4Linux初始化

media设备节点初始化与Video4Linux初始化 文章目录 media设备节点初始化与Video4Linux初始化media设备节点初始化Video4Linux初始化 media设备节点初始化 media_devnode_init函数是一个内核初始化函数&#xff0c;用于在Linux内核启动期间进行设备节点初始化。 函数的主要作用…

复习:遥感图像解译复习整理

惭愧&#xff0c;这个课程从始自终就没有认真学过&#xff0c;一部分是因为自己的原因&#xff0c;另一部分也是因为自己的原因。因此&#xff0c;对于整理的资料有不足之处请指正。 另外&#xff0c;资料自word复制&#xff0c;没有时间整理博客的格式。 -- 2023年05月19日记…

深度学习训练营之Densenet网络

深度学习训练营 原文链接环境介绍前言设计理念网络结构实验结果和讨论pytorch实现DenseNet附录 原文链接 &#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f366; 参考文章&#xff1a;365天深度学习训练营-第J3周&#xff1a;Densenet网络学习&…

第一代AIGC硬件悄然爆发

文 | 智能相对论 作者 | 叶远风 看起来&#xff0c;这可能是一副正常的黑框眼镜&#xff0c;你戴上去彬彬有礼、斯斯文文&#xff1b; 实际上&#xff0c;它里边还装了一个“小伙伴”&#xff0c;你随时可以与它交流&#xff0c;谈天说地或者提出各种问题接受它的帮助&#x…

深度学习之构建MPL神经网络——泰坦尼克号乘客的生存分析

大家好&#xff0c;我是带我去滑雪&#xff01; 本期使用泰坦尼克号数据集&#xff0c;该数据集的响应变量为乘客是生存还是死亡&#xff08;survived&#xff0c;其中1表示生存&#xff0c;0表示死亡&#xff09;&#xff0c;特征变量有乘客舱位等级&#xff08;pclass&#x…

广告投放的关键成功因素:广告归因与广告效果监测

在当今竞争激烈的市场环境中&#xff0c;广告归因和广告效果监测成为了广告投放中至关重要的环节。通过深入了解广告归因和广告效果监测的方法&#xff0c;企业可以更好地评估广告投放的成效&#xff0c;并做出精确的决策&#xff0c;以提高广告效果和最大化投资回报。 本文将带…

昆仑万维“勇闯”百模大战:一个“无懈可击”的商业故事话本?

文丨智能相对论 作者丨沈浪 新能源火了做新能源&#xff0c;元宇宙火了做元宇宙。 如果一个热点领域没有昆仑万维的身影&#xff0c;那一定是这个领域还不够“热”&#xff0c;爆不了。 但凡是热到爆的领域&#xff0c;昆仑万维虽迟但到。 不过&#xff0c;这样说可能有些…

【计算机网络基础】章节测试3 数据链路层

文章目录 判断题选择题辨析题应用题 判断题 相对于广域网而言&#xff0c;局域网的误码率较低。√ 交换机是依据IP地址来转发数据包的。 局域网使用集线器作为网络连接设备时&#xff0c;逻辑上是星型结构。 PPP协议应首先满足的需求是简单&#xff0c;以使得协议在实现的时…

Go语言的学习【2】基础语法

目录 代码组成部分字符串格式化字符数据类型变量遇到的问题及解决办法1 代码组成部分 Go 程序可以由多个标记组成&#xff0c;可以是关键字&#xff0c;标识符&#xff0c;常量&#xff0c;字符串&#xff0c;符号。 在 Go 程序中&#xff0c;一行代表一个语句结束。 如果你…

【linux】图文并茂,让你轻松掌握Linux基本指令

目录 一&#xff0c;前提 二&#xff0c; 在root身份下&#xff0c;管理用户 1. 判断身份 2. 创建用户 3. 销毁用户 三&#xff0c;文件增&#xff0c;删&#xff0c;移动指令 1. pwd——查看路径 2. ps ——打开文件目录 3. touch——创建文件 4. nano——打开文件 5.…

【大数据】Presto(Trino)REST API 与执行计划介绍

文章目录 一、概述二、环境准备三、常用 REST API1&#xff09;worker 节点优雅退出2&#xff09;提交SQL查询请求3&#xff09;获取查询状态4&#xff09;获取查询结果5&#xff09;取消查询请求6&#xff09;获取Presto 节点信息7&#xff09;获取Presto服务器使用统计信息8&…

功率放大器电路中的三极管和MOS管,究竟有什么区别?

学习模拟电子技术基础&#xff0c;和电子技术相关领域的朋友&#xff0c;在学习构建功率放大器电路时最常见的电子元器件就是三极管和场效应管&#xff08;MOS管&#xff09;了。那么三极管和MOS管有哪些联系和区别呢&#xff1f;在构建功率放大器电路时我们要怎么选择呢&#…

干货 | 利用SPSS进行高级统计分析第一期

Hello&#xff0c;大家好&#xff01; 这里是壹脑云科研圈&#xff0c;我是喵君姐姐&#xff5e; 你是否还在为分析实验数据而感到头疼&#xff1f;你是否还在苦于自己不知道如何选择合适的模型来分析数据&#xff1f; 本期我们就来为大家带来了利用SPSS软件进行高级统计分析…

【学习日记】在不可联网电脑上安装Python和深度学习环境

测试环境 Hyer-V上开了个虚拟机&#xff0c;win7-64位企业版&#xff0c;全新未安装任何环境的最基本的操作系统。 因为不联网安装&#xff0c;而且是win7这种古老的操作系统&#xff0c;确实会遇到很多问题。做个记录。 安装Python 打开python-3.7.8.exe 安装程序 此时可能…

离岗识别 yolov5模型

离岗识别通过yolov5网络模型技术&#xff0c;离岗识别可以自动识别现场画面中人员离岗脱岗睡岗等行为&#xff0c;发现违规行为立即抓拍告警。YOLOv5在YOLOv4算法的基础上做了进一步的改进&#xff0c;检测性能得到进一步的提升。虽然YOLOv5算法并没有与YOLOv4算法进行性能比较…

Unity3d 开发Pico4程序闪退弹窗【版权保护】检测的解决方法

前言 最近在进行基于Pico4的应用开发&#xff0c;然后在部分设备上程序是无法正常进入的&#xff0c;而且总是弹出这个版权保护的窗口&#xff1a; 按理说正常的自己开发的测试的程序不应该有这种限制&#xff0c;查询后发现是 PICO 内置了版权保护机制。应用上架后&#xff0…