目录

接口的使用

仿真的结束

类的例化和类的成员


接口的使用

问题1.1:可以看到之前的实验 channel initiator 发送的数据例如 valid 和 data 与时钟 clk 均在同一个变化沿,没有任何延迟,这种0延迟的数据发送不利于波形查看和阅读,因此在已有代码的基础上使用 intf.ck 的方式来做数据驱动,并且再观察波形,查看驱动的数据与时钟上升沿的延迟是多少?

采用 intf.ck 来做数据驱动,代码如下:

编辑

编辑

上升沿后1ns驱动数据

波形如下:

编辑

问题1.2:为了更好地控制相邻数据之间的空闲间隔,引入一个变量 idle_cycles, 它表示相邻有效数据之间的间隔。已有代码会使得有效数据之间保持固定的一个空闲周期,我们需要使用 idle_cycles 变量, 来灵活控制有效数据之间的空闲周期。通过这个方法,在 tb 的 initial 块中我们通过方法 set_idle_cycles() 使得三个 channel initiator 的空闲周期变为 0, 即可以实现有效数据的连续发送。

编辑

当 idle_cycle = 0; 相邻数据之间就紧密发送,无间隔

波形如下:

编辑


仿真的结束

​编辑

​编辑

回顾 fork join 的知识: fork join 内部是并行执行的

1.fork join:当fork join内部全部执行完之后,才会继续往下顺序执行;

2.fork join_none:fork join_none语句块执行的同时,父线程会继续执行,即全部并行执行;

3.fork join_any:执行到fork join_any内部语句时,当有任意一个语句执行完,那么后续的父类线程也会继续顺序执行。

task automatic burst_test();
// verification component initialization
chnl0_gen.initialize(0);
chnl1_gen.initialize(1);
chnl2_gen.initialize(2);
chnl0_init.set_name("chnl0_init");
chnl1_init.set_name("chnl1_init");
chnl2_init.set_name("chnl2_init");
chnl0_init.set_idle_cycles(0);
chnl1_init.set_idle_cycles(0);
chnl2_init.set_idle_cycles(0);
$display("burst_test initialized components");
wait (rstn === 1'b1);
repeat(5) @(posedge clk);
$display("burst_test started testing DUT");
// Please check the SV book for fork-join basic knowledge
// and get understood it is for parallel thread running
fork
repeat(500) chnl0_init.chnl_write(chnl0_gen.get_data());
repeat(500) chnl1_init.chnl_write(chnl1_gen.get_data());
repeat(500) chnl2_init.chnl_write(chnl2_gen.get_data());
join
$display("basic_test finished testing DUT");
endtask

​编辑

task automatic fifo_full_test();
// verification component initialization
chnl0_gen.initialize(0);
chnl1_gen.initialize(1);
chnl2_gen.initialize(2);
chnl0_init.set_name("chnl0_init");
chnl1_init.set_name("chnl1_init");
chnl2_init.set_name("chnl2_init");
chnl0_init.set_idle_cycles(0);
chnl1_init.set_idle_cycles(0);
chnl2_init.set_idle_cycles(0);
$display("fifo_full_test initialized components");
wait (rstn === 1'b1);
repeat(5) @(posedge clk);
$display("fifo_full_test started testing DUT");
fork
repeat(500) chnl0_init.chnl_write(chnl0_gen.get_data());
repeat(500) chnl1_init.chnl_write(chnl1_gen.get_data());
repeat(500) chnl2_init.chnl_write(chnl2_gen.get_data());
join_none
fork
wait(chnl0_init.intf.ch_margin == 'h20);
wait(chnl1_init.intf.ch_margin == 'h20);
wait(chnl2_init.intf.ch_margin == 'h20);
join
$display("fifo_full_test finished testing DUT");
endtask


类的例化和类的成员

​编辑

​编辑

这里的例化 是类的例化 先声明句柄,再创建对象

  chnl_intf chnl0_if(.*);
chnl_intf chnl1_if(.*);
chnl_intf chnl2_if(.*); chnl_initiator chnl0_init;
chnl_initiator chnl1_init;
chnl_initiator chnl2_init;
chnl_generator chnl0_gen;
chnl_generator chnl1_gen;
chnl_generator chnl2_gen; initial begin
// USER TODO 3.1
// instantiate the components chn0/1/2_init chnl0/1/2_gen
chnl0_init = new("chnl0_init");
chnl1_init = new("chnl1_init");
chnl2_init = new("chnl2_init");
chnl0_gen = new(0);
chnl1_gen = new(1);
chnl2_gen = new(2);

​编辑

/ USER TODO 3.2
// assign the interface handle to each chnl_initiator objects
chnl0_init.set_interface(chnl0_if);
chnl1_init.set_interface(chnl1_if);
chnl2_init.set_interface(chnl2_if);

​编辑


basic_test();
burst_test();
fifo_full_test();
$finish();

完整的 initial 块就是

  initial begin
// USER TODO 3.1
// instantiate the components chn0/1/2_init chnl0/1/2_gen
chnl0_init = new("chnl0_init");
chnl1_init = new("chnl1_init");
chnl2_init = new("chnl2_init");
chnl0_gen = new(0);
chnl1_gen = new(1);
chnl2_gen = new(2); // USER TODO 3.2
// assign the interface handle to each chnl_initiator objects
chnl0_init.set_interface(chnl0_if);
chnl1_init.set_interface(chnl1_if);
chnl2_init.set_interface(chnl2_if); // USER TODO 3.3
// START TESTs
$display("*****************all of tests have been finished********************");
basic_test();
burst_test();
fifo_full_test();
$finish();
end

​编辑

  class chnl_generator;
chnl_trans trans[$];
int num;
int id;
chnl_trans t //这个句柄的位置
function new(int n);
this.id = n;
this.num = 0;
t = new(); // 这个创建对象实例的位置都应该放在下面的函数中
endfunction
function chnl_trans get_trans();
//chnl_trans t = new();
t.data = 'h00C0_0000 + (this.id<<16) + this.num;
t.id = this.id;
t.num = this.num;
this.num++;
this.trans.push_back(t);
return t;
endfunction
endclass: chnl_generator

trans[$]用于存放句柄。在function new(int n)中创建实例,三个chnl在初始化时只创建了一个实例,而在get_trans()函数中只有一个实例的话,不论data产生了多少,最终句柄都指向一个对象,只有一个数字,因为数据不断被覆盖直至最后一个。

正确的是应该在get_trans()内创建实例,每次调用产生数据都会创建一个对象,并将句柄保存至trans[$]中,如果repeat(500),那么会产生500个句柄和500个不同的数据。

MCDF实验2的更多相关文章

  1. [原] 利用 OVS 建立 VxLAN 虚拟网络实验

    OVS 配置 VxLAN HOST A ------------------------------------------ | zh-veth0(10.1.1.1) VM A | | ---|--- ...

  2. Android中Activity的四大启动模式实验简述

    作为Android四大组件之一,Activity可以说是最基本也是最常见的组件,它提供了一个显示界面,从而实现与用户的交互,作为初学者,必须熟练掌握.今天我们就来通过实验演示,来帮助大家理解Activ ...

  3. SEED实验系列文章目录

    美国雪城大学SEEDLabs实验列表 SEEDLabs是一套完整的信息安全实验,涵盖本科信息安全教学中的大部分基本原理.项目组2002年由杜文亮教授创建,目前开发了30个实验,几百所大学已采用.实验楼 ...

  4. 物联网实验4 alljoyn物联网实验之手机局域网控制设备

    AllJoyn开源物联网协议框架,官方描述是一个能够使连接设备之间进行互操作的通用软件框架和系统服务核心集,也是一个跨制造商来创建动态近端网络的软件应用.高通已经将该项目捐赠给了一个名为“AllSee ...

  5. (转)linux下和云端通讯的例程, ubuntu和openwrt实验成功(一)

    一.  HTTP请求的数据流总结#上传数据, yeelink的数据流如下POST /v1.0/device/4420/sensor/9089/datapoints HTTP/1.1Host: api. ...

  6. (原创) alljoyn物联网实验之手机局域网控制设备

    AllJoyn开源物联网协议框架,官方描述是一个能够使连接设备之间进行互操作的通用软件框架和系统服务核心集,也是一个跨制造商来创建动态近端网络的软件应用.高通已经将该项目捐赠给了一个名为“AllSee ...

  7. 实验:Oracle直接拷贝物理存储文件迁移

    实验目的:Oracle直接拷贝物理文件迁移,生产库有类似施工需求,故在实验环境简单验证一下. 实验环境: A主机:192.168.1.200 Solaris10 + Oracle 11.2.0.1 B ...

  8. Oracle RAC 更换存储实验

    实验环境准备: RHEL 6.5 + Oracle 11.2.0.4 RAC (2nodes) OCR和Voting Disk使用的是OCR1磁盘组,底层对应3个1G大小的共享LUN,一般冗余: DA ...

  9. Vertica集群扩容实验过程记录

    需求: 将3个节点的Vertica集群扩容,额外增加3个节点,即扩展到6个节点的Vertica集群. 实验环境: RHEL 6.5 + Vertica 7.2.2-2 步骤: 1.三节点Vertica ...

随机推荐

  1. Ubuntu安装docker-compose(摘自官网,自用)

    安装 Docker Compose 预计阅读时间:8分钟 加速 Docker 桌面中的新功能 Docker Desktop 可帮助您在 Mac 和 Windows 上轻松构建.共享和运行容器,就像在 ...

  2. Java多线程与线程池技术

    一.序言 Java多线程编程线程池被广泛使用,甚至成为了标配. 线程池本质是池化技术的应用,和连接池类似,创建连接与关闭连接属于耗时操作,创建线程与销毁线程也属于重操作,为了提高效率,先提前创建好一批 ...

  3. Linux centos7系统列出systemd下所有正在运行的服务

    Linux系统提供各种系统服务(如进程管理.登录.syslog.cron等)和网络服务.Linux支持不同的方法来管理服务(启动.停止.重启.在系统启动时的自动启动等),通常通过流程或服务管理器. 大 ...

  4. java实现ssh连接工具类

    import ch.ethz.ssh2.Connection;import ch.ethz.ssh2.Session;import ch.ethz.ssh2.StreamGobbler;import ...

  5. Java语言学习day34--8月09日

    ##13Math类的方法_1 A:Math类中的方法 /* * static double sqrt(double d) * 返回参数的平方根 */ public static void functi ...

  6. struts2绕过waf读写文件及另类方式执行命令

    之前碰到过好几次Struts2,还都是016,项目.众测都遇到过,每次都只是证明了一下存在,由于waf的存在,没有深入去利用,这里简单的记录下. 0x01 背景 xray或者Struts2漏扫可以扫到 ...

  7. 分布式任务调度平台XXL-JOB安装及使用

    一.为什么需要任务调度平台 在Java中,传统的定时任务实现方案,比如Timer,Quartz等都或多或少存在一些问题: 不支持集群.不支持统计.没有管理平台.没有失败报警.没有监控等等而且在现在分布 ...

  8. 简单几步解决ie打不开闪退的问题 亲测有效

    起因: 银行U盾插入 IE自动打开银行门户网站 打不开 闪退 不插入之后 IE还是闪退, 修复之法 清除IE扩展 一些自己安装的扩展或是被恶意安装的扩展插件会导致IE无法启动 1. 按住windows ...

  9. [题解] [AGC024F] Simple Subsequence Problem

    题目大意 有一个 01 串集合 \(S\),其中每个串的长度都不超过 \(N\),你要求出 \(S\) 中至少是 \(K\) 个串的子序列的最长串,如果有多解,输出字典序最小的那组解. 由于 \(S\ ...

  10. Linux学习教程 | 全文目录

    本教程最大的特点是通俗易懂,并且非常详细,花费 7 天时间即可快速了解 Linux. 第一章 Linux简介 1.1 操作系统是什么,操作系统概述 1.2 Linux是什么,有哪些特点? 1.3 Li ...