• 路科验证-实验一详细步骤


    一.题目要求

    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。

    二.从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
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    (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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    (2)仿真结果

    • 待定

    5.问题五步骤

    (5)如果将’timescale 1ns/1ps修改为’timescale 1ps/1ps,那么仿真中的时钟周期是否发生变化了呢,这是为什么呢?

    在这里插入图片描述

    在这里插入图片描述

    • 没有发生变化,原因:暂时不知道

    4.数组的使用

    (1)如果现在要求同学们对每一个slave的数据发出100个数,那么如何实现呢?
    (2)如果现在生成100个数,并对它们按照目前的数值规则进行赋值,请同学们创建3个动态数组,分别放置要发送3个slave的数据。

    问题一步骤

    如果要对每一个channel发送100个数据或者更多个数据,可以创建动态数组,分别放置要发送给每一个channel的数据

    logic [31:0] chnl0_arr[];
    logic [31:0] chnl1_arr[];
    logic [31:0] chnl2_arr[];
    
    • 1
    • 2
    • 3

    问题二步骤

    然后每个动态数组要事先生成数据

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    问题三步骤

    接下来利用数组生成的数据,读取数据并发送给每一个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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
  • 相关阅读:
    Python环境搭建之OpenCV
    在Pikachu平台中利用代码注入漏洞的编辑框在哪?
    FootPrintTools...
    基于Unity设计的井字棋小游戏
    网络流中反向边作用
    生产者/消费者模型
    Lua语法之简单变量
    Redis学习
    C#_值类型与引用类型 及 值参数与引用参数
    【超分】A Benchmark for Chinese-English Scene Text Image Super-resolution
  • 原文地址:https://blog.csdn.net/qq_44943193/article/details/125513341