一.题目要求
1.从verilog到sv
(1)将tb1修改为tb1.sv,按照之前的步骤进行仿真,查看仿真的行为是否同tb1.v相似,结果说明什么?
(2)将信号变量类型由reg或者wire修改为logic类型,再仿真编译看是否与之前的行为相似,这是为什么?
(3)在步骤的基础之上,将rstn的类型由logic改成bit类型,再仿真编译,行为是否和步骤2一致呢,为什么?
2.方法task和函数function
在tb2.sv文件中,可以看出不同于tb1.sv文件的是,之前产生时钟和发起复位的两个Initial过程快语句都被两个task即clk_gen()和rstn_gen()取代了,完成实验的部分:
(1)不做修改的情况下,对tb2.sv进行编译仿真,时钟信号和复位信号还正常吗?为什么?
(2)同学们在路桑标记的两个initial块中分别调用产生时钟和复位的task,再编译仿真查看时钟信号和复位信号,是否恢复正常呢?
(3)为什么要将两个task和两个initial块中调用,这是为什么呢?是否可以在一个initial块中调用呢?如果可以,调用的顺序是什么?
(4)同学们是否可以读出目前时钟的周期和频率呢?如何测量呢?如果我们想进化clk_gen()方法,使其变为可以设置时钟周期的任务clk_gen(20),看看波形中的时钟周期是否变为20ns呢?
(5)如果将’timescale 1ns/1ps修改为’timescale 1ps/1ps,那么仿真中的时钟周期是否发生变化了呢,这是为什么呢?
3.数组的使用
(1)如果现在要求同学们对每一个slave的数据发出100个数,那么如何实现呢?
(2)如果现在生成100个数,并对它们按照目前的数值规则进行赋值,请同学们创建3个动态数组,分别放置要发送3个slave的数据。
(3)接下来利用生成的数组数据,将他们读取并发送给三个channel。
4.验证结构
二.从verilog到sv实验步骤
1.问题一实验步骤
(1)新建工程
- 注意不要出现中文路径
(2)导入文件 - add Existing File
(3)编译仿真
- 仿真编译的时候首先编译设计文件arbiter.v和slave.fifo.v,然后编译mcdt.v,最后编译tb1.v,
- 编译使用complie Selected
(4)查看波形
- 使用simulate without Optimization
- 点击dut,添加波形,使用鼠标的滚轮键,然后点击上边的run,可以设置run的时间
其中信号的后缀为 -i是输入信号,-o是输出信号,-s是内部信号
- 修改为sv后缀之后跑仿真
- 结果相同,说明sv支持所有关于verilog的语法
2.问题二步骤
(1)新建工程,添加工程,仿真,添加波形,这些都省略了哈,改修变量为logic之后,直接给出仿真结果对比
- 结果相同,logic简化了变量的行为
3.问题三步骤
- 将logic修改为bit,观察rstn的变化
- 结果相同,不知道为啥,我没看出变化
三.方法task和函数function实验步骤
1.问题一步骤
- 对tb2.sv进行编译,时钟信号和复位信号不正常,原因为:task中的时钟复位未调用
2.问题二步骤
(1)添加两个代码
// clock generation
task clk_gen();
clk <= 0;
forever begin
#5 clk<= !clk;
end
endtask
initial begin
clk_gen();
end
// reset trigger
// create task rstn_gen()
task rstn_gen();
#10 rstn <= 0;
repeat(10) @(posedge clk);
rstn <= 1;
endtask
initial begin
rstn_gen();
end
(2)仿真结果
- 恢复正常
3.问题三步骤
- clk_gen()和rstn_gen()不可以放在一个initial块里面,时钟在前只有时钟,没有复位,如果复位在前,只有复位没有时钟
- 原因:显然仿真波形里面只产生了clock时钟信号,并没有产生复位信号,这是因为多个initial块是并行的,而把时钟信号和复位信号放在一个initial块里面,在initial块内部的执行顺序是串行的,执行clk_gen()时,forever会一直执行,不断产生时钟信号,导致rstn_gen()方法无法调用执行。
4.问题四步骤
(1)修改代码为
task clk_gen(int peroid);
clk <= 0;
forever begin
#peroid clk<= !clk;
end
endtask
initial begin
clk_gen(20);
end
(2)仿真结果
- 待定
5.问题五步骤
(5)如果将’timescale 1ns/1ps修改为’timescale 1ps/1ps,那么仿真中的时钟周期是否发生变化了呢,这是为什么呢?
- 没有发生变化,原因:暂时不知道
四.数组的使用
(1)如果现在要求同学们对每一个slave的数据发出100个数,那么如何实现呢?
(2)如果现在生成100个数,并对它们按照目前的数值规则进行赋值,请同学们创建3个动态数组,分别放置要发送3个slave的数据。
1.问题一步骤
如果要对每一个channel发送100个数据或者更多个数据,可以创建动态数组,分别放置要发送给每一个channel的数据
logic [31:0] chnl0_arr[];
logic [31:0] chnl1_arr[];
logic [31:0] chnl2_arr[];
2.问题二步骤
然后每个动态数组要事先生成数据
initial begin
chnl0_arr = new[100];
chnl1_arr = new[100];
chnl2_arr = new[100];
foreach(chnl0_arr[i]) begin
chnl0_arr[i] = 'h00C0_00000 + i;
chnl1_arr[i] = 'h00C1_00000 + i;
chnl2_arr[i] = 'h00C2_00000 + i;
end
end
3.问题三步骤
接下来利用数组生成的数据,读取数据并发送给每一个channel
initial begin
@(posedge rstn);
repeat(5) @(posedge clk);
// channel 0 test
// TODO use chnl0_arr to send all data
foreach(chnl0_arr[i]) chnl_write(0, chnl0_arr[i]);
// channel 1 test
// TODO use chnl1_arr to send all data
foreach(chnl1_arr[i]) chnl_write(1, chnl1_arr[i]);
// channel 2 test
// TODO use chnl2_arr to send all data
foreach(chnl2_arr[i]) chnl_write(2, chnl2_arr[i]);
end