MCDF-实验1

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

提示:这里可以添加本文要记录的大概内容:

从Verilog到SV的进场——tb1.sv

首先将测试文件tb1.v改为sv文件,编译仿真,查看结果是否和实验0一致;一致
其次将信号变量由reg或者wire修改为logic类型,编译仿真,查看结果是否有变化;一致
最后将rstn的类型由logic修改为bit类型,再编译仿真,查看结果是否一致。一致


提示:以下是本篇文章正文内容,下面案例可供参考

一、方法task和函数function——tb2.sv

  • 在原tb1.sv基础上将产生时钟和发起复位的initial块用任务clk_gen()和rstn_gen()取代,修改文件名为tb2。编译仿真,使用和复位信号是否正常。

仿真无波形,原因在于两个任务没有进行调用。

  • 使用一个/两个initial块来分别调用clk_gen()和rstn_gen()

使用两个initial块可以正常产生时钟波形和复位信号;在一个initial块中直接调用会陷入时钟产生的forever-loop中无法执行复位信号,如果先调用复位任务也不行,因为它无法等到时钟上升沿,也就无法结束。综上,不能直接使用initial块,需要添加并行线程fork…join_none,同时调用这两个任务。
在这里插入图片描述
在这里插入图片描述

  • 测量时钟周期并修改代码使时钟周期可调
    添加cursor, 再通过工具栏左上角,找到下一个上升沿即可根据两个cursor间的时间间隔直到时钟周期为10ns。
    在这里插入图片描述
    可以设置时间延迟变量,作为clk_gen()任务的参数传递。或者可以使用把时间值存放到变量的方法绿皮书P62页。这里我使用的是第一种方法
    在这里插入图片描述
    在这里插入图片描述
  • 将时间单位改成1ps,观察波形时钟周期发生明显变化。

二、数组的使用——tb3.sv

  • 对每个slave的数据发出100个数(32位),将递增生成这100个数据并放入数组,再读取送入channel
    可以使用repeat语句来重复发送100次,每次发送的数值随机。但是这样不符合实验要求,要求发送的数据每次递增,结合数组的方法,可以使用for和foreach来生成100个数据,数组可以使用动态数组以便代码重用。需要注意的是动态数组使用new[100]来设置数组的大小,区分句柄对象的创建。接下来使用这两种方法。

for语句实现

在这里插入图片描述
这样100个数据就产生好了,接下来要将它们发送给channel。这需要对task chnl_write做一些修改。
在这里插入图片描述
仿真波形如下:只发送了最后一个数据99。原因在于上一个数据没有及时发送出去,下一个数据紧接着就过来了,导致数据被不断地覆盖,直到最后一个数据。修改这部分代码使得一个数据发送出去后再接受下一个数据。
在这里插入图片描述

【解决】:应该将满足case条件的执行语句全部放入for循环内
在这里插入图片描述
在这里插入图片描述


foreach语句实现

在这里插入图片描述
仿真结果如下:
在这里插入图片描述


三、验证结构——tb4.sv

将DUT与激励发生器分开,即激励方法chnl_write()封装在新的模块chnl_initiator中。在测试代码中分别例化三个通道的实例。
在这里插入图片描述

在这里插入图片描述

在chnl_initiator定义了三个方法:
1.chnl_idle()要实现的一个时钟周期的空闲,在该周期中,ch_valid应为低,ch_data应为0。
在这里插入图片描述

2.chnl_write()实现一次有效的数据写入并随后调用chnl_idle(),要求只有当valid和ready信号为高时,数据写入才算成功,j如果ready信号为低则应该保持数据和valid信号保持数据但不写入,直到ready拉高时。数据写入才算成功。
在这里插入图片描述

3.set_name()即设置实例的名称,在initial过程块中data test中,在发送数据前设置channel initiator实例名称,以便调试。
在这里插入图片描述
测试代码:
在这里插入图片描述
仿真波形:数据正常发送。
在这里插入图片描述


四、拓展

  • 是否可以让三个channel_slave各自的chX_ready信号可以拉低,如果拉低了,这代表什么?考虑如何让发送更多更快的数据,让mcdt的三个chX_ready信号可以拉低。
    在这里插入图片描述
    从slave_fifo设计文件中可以看到,如果chx_ready信号拉低则代表FIFO满状态,但是每存入一个数据,又会被拿走,这决定了FIFO不会满状态,除非连续发送足够多的数据,那么放入的速度比拿出去的快,则会出现容量为0的情况。详见实验2

总结

1.不能对动态数组内的元素进行非阻塞赋值
2.for-loop中参数用分号;隔开
3.动态数组可以作为任务/函数参数来传递,传递办法有两种,一是传递整个数组,而是传递数组内的单个元素

传递整个数组:
logic [31:0] chnl_array[];
chnl_array = new[100];
task temp (input logic [31:0] data_array[])

endtask
temp(chnl_array);

6.22修改

在tb4中chnl_write()代码有些问题,虽然ready没有拉高但是数据依旧是同步的,只是不能写入。因此并非等到ready为高才能同步数据。而是在同步数据后等待ready
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值