IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> 【路科V0】SV实验2 【Sending PacketsThrough Router】 -> 正文阅读

[系统运维]【路科V0】SV实验2 【Sending PacketsThrough Router】

Lab2的学习目标是:

  1. 拓展lab1中的测试平台,从一个输入端向一个输出端发送数据包。
  2. 用新的测试平台来编译和仿真设计文件。

在这次Lab中,你将继续去搭建测试平台上的相关组件(component) :

  • 激励产生器(Stimulus Generator)
  • 驱动器(Driver)
  • 等。

????????你会使用一些的子程序(routine)去把一个数据包从输入端口3发送到输出端口7,并观察到这个数据包的payload。

在该实验完成时,你将得到如下验证结构。

任务一:声明程序(program)的全局变量

通过路由器发送数据包需要指定

  • 使用哪个输入端口和输出端口(地址)
  • 发送什么数据

为了使引用这些变量变得简单,您将它们声明为程序全局变量

1、用文本编辑器打开 test.sv文件。

2.、为数据包声明程序全局变量( program globals):

program automatic test(router_io.TB rtr_io);
    int run for_n packets;    //number of packets to test

    bit[ 3:0] sa;             // source address (input port)
    bit [3:0] da;             // destination address (output port)
    logic[7:0] payload[$];   // packet data array
                        //logic stores 0,1,x and z values
    ....
    ...
endprogram:test

任务二:产生数据包(?Packet Data)

?????????在lab1中,你通过调用reset()子程序来配置(Configure)待测试模块。

? ? ? ? ?接着你创建一个Task: gen()来继续发展这个测试平台。

????????(gen()是一个可以产生测试激励的子程序)

?1、在程序的initial块中的reset()后面,调用gen()任务。

program automatic test(router_io.TB rtr_io);
    int run for_n packets;    //number of packets to test

    bit[ 3:0] sa;             // source address (input port)
    bit [3:0] da;             // destination address (output port)
    logic[7:0] payload[$];   // packet data array
                        //logic stores 0,1,x and z values

    initial begin
        reset();
        gen();    //产生测试激励
    end 
    ...
endprogram:test

2、在任务 reset() 代码块之后,声明gen()任务:

program automatic test(router_io.TB rtr_io);
    int run for_n packets;    //number of packets to test

    bit[ 3:0] sa;             // source address (input port)
    bit [3:0] da;             // destination address (output port)
    logic[7:0] payload[$];   // packet data array
                        //logic stores 0,1,x and z values

    initial begin
        reset();
        gen();    //产生测试激励
    end 

    task reset ( );
        ...
    endtask: reset
//gen task
    task gen () ;
    ...
    endtask: genend

endprogram: test

3、在 gen ( ) 任务的主体中:

  • 将 sa(源地址) 设置为 3,将 da(目标地址) 设置为 7。
  • 用 2 到 4 个随机字节(random bytes)来填满有效负载序列(payload queue) 。

完成后,您的代码应如下所示:

program automatic test(router_io.TB rtr_io);
    int run for_n packets;    //number of packets to test

    bit[ 3:0] sa;             // source address (input port)
    bit [3:0] da;             // destination address (output port)
    logic[7:0] payload[$];   // packet data array
                        //logic stores 0,1,x and z values

    initial begin
        reset();
        gen();    //产生测试激励
    end 

    task reset ( );
        ...
    endtask: reset

//gen task
   task gen ( );
    sa = 3 ;da = 7 ;
    payload.delete ( ) ;//清空队列
    repeat ($urandom_range ( 2,4) )
       payload.push_back ( $urandom) ;//往队列送数据,repeat(2-4)次,每次写入一个数据
endtask: gen
//系统函数$urandom提供了一种生成伪随机数的机制。
//这个函数每次调用时返回一个新的32位随机数。数字为无符号。

endprogram:test

任务三:创建发送数据包的程序(Routine)

?send_addr()、send_pad()、send_payload()封装在send()里。

在数据包的信息产生后,你准备好创建Transactor和Driver来发送数据包。

把一个数据包发送通过路由器的行为,可以通过以下三个进程来完成:

  1. 发送Destination Address(目标地址)
  2. 发送padding bits。(空闲)
  3. 发送payload。(数据队列)

其中每一个进程将发展成为driver routine中的一个独立部分(device) 。

Driver中各部件和Transactor的区别是:

  • 当Transactor调用device driver时,device driver和硬件信号是直接相互作用的。

这些抽象的分层可以使testbench的子程序(routine)更容易管理,更好复用,更加可靠。

以下的步骤可以帮助你构建这些子程序

1、在initial块中,在 gen() 语句之后立即调用 send() 任务发送数据包。

program automatic test(router_io.TB rtr_io);
    int run for_n packets;    //number of packets to test

    bit[ 3:0] sa;             // source address (input port)
    bit [3:0] da;             // destination address (output port)
    logic[7:0] payload[$];   // packet data array
                        //logic stores 0,1,x and z values

    initial begin

       
         reset();
         gen();    //产生测试激励数据包
         send();   //发送数据包
   end

    ...
endprogram:test

2、在调用 send( ) 调用之后,仿真10 个时钟周期。

????????这将允许观察从路由器出来的数据。否则,当您在 DVE 中查看波形时,输出将被截断。

program automatic test(router_io.TB rtr_io);
    int run for_n packets;    //number of packets to test

    bit[ 3:0] sa;             // source address (input port)
    bit [3:0] da;             // destination address (output port)
    logic[7:0] payload[$];   // packet data array
                        //logic stores 0,1,x and z values

    initial begin
        $vcdpluson;
        run_fornpackets=21;
       
        reset();
 
        repeat(run_for_n _packets) begin
           gen();    //产生测试激励数据包
           send();   //发送数据包
        end

        repeat(10)@(rtr_io.cb ) ;
    end

//task
    ....
    ...


endprogram:test

3、在program块中添加任务send()的声明。

program automatic test(router_io.TB rtr_io);
    int run for_n packets;    //number of packets to test

    bit[ 3:0] sa;             // source address (input port)
    bit [3:0] da;             // destination address (output port)
    logic[7:0] payload[$];   // packet data array
                        //logic stores 0,1,x and z values

    initial begin
       ...     
    end

  task reset ( );
        ...
  endtask: reset

  task gen () ;
    ...
  endtask: genend

  task send();
     ...
  endtask: send

    ...
endprogram:test

4、在 send( ) 任务中,编写以下操作:

  • 调用send_addrs()?
  • 调用send_pad()
  • 调用send_payload()
program automatic test(router_io.TB rtr_io);
    int run for_n packets;    //number of packets to test

    bit[ 3:0] sa;             // source address (input port)
    bit [3:0] da;             // destination address (output port)
    logic[7:0] payload[$];   // packet data array
                        //logic stores 0,1,x and z values

    initial begin
       ...     
    end

  task reset ( );
        ...
  endtask: reset

  task gen () ;
    ...
  endtask: genend

  task send();
     send_addrs()?;
     send_pad();
     send_payload();
  endtask: send

    ...
endprogram:test

?5.创建 send_addrs ( ) 任务。

这个Driver的部件将会驱动4位的地址进入Router

program automatic test(router_io.TB rtr_io);
    int run for_n packets;    //number of packets to test

    bit[ 3:0] sa;             // source address (input port)
    bit [3:0] da;             // destination address (output port)
    logic[7:0] payload[$];   // packet data array
                        //logic stores 0,1,x and z values

    initial begin
       ...     
    end

    ...
  task send();
     send_addrs()?;
     send_pad();
     send_payload();
  endtask: send

  task send_addrs()?;
     ...
  endtask: send_addrs

    ...
endprogram:test

6. 在 send_addrs ( ) 中,编写以下操作:?

  1. 驱动frame_n信号作为每一个路由器的配置内容。
  2. 驱动目标地址通过din信号传送。
  3. 把din作为单bit的连续信号。使用一个环结构来驱动din,以每周期一bit的速度循环四个周期。(din 是一个单比特串行信号,使用循环结构在每个时钟周期驱动 din 一位,持续四个周期。 )
program automatic test(router_io.TB rtr_io);
    int run for_n packets;    //number of packets to test

    bit[ 3:0] sa;             // source address (input port)
    bit [3:0] da;             // destination address (output port)
    logic[7:0] payload[$];   // packet data array
                        //logic stores 0,1,x and z values

    initial begin
       ...     
    end

    ...
  task send();
     send_addrs()?;
     send_pad();
     send_payload();
  endtask: send

  task send_addrs()?;
     rtr_io.cb.frame_n[sa] <=1'b0;
    for(int i=0; i<4; i++) begin
        rtr_io.cb.din[sa] <= da[i];
     @(rtr_io.cb) ;
   end
  endtask:send_addrs

    ...
endprogram:test

注意:

每个端口由 frame_n.din 和 valid_n 中的一个单独的位表示。 确保指定正确的位。

将输入端口 3 的 frame_n 信号驱动为“1”的形式为:

rtr_io.cb .frame_n [ 3] <= 1'b1 ;

?7、创建 send_pad ( ) 任务。 这个device driver可以驱动五个pad bits进入路由器。

program automatic test(router_io.TB rtr_io);
    int run for_n packets;    //number of packets to test

    bit[ 3:0] sa;             // source address (input port)
    bit [3:0] da;             // destination address (output port)
    logic[7:0] payload[$];   // packet data array
                        //logic stores 0,1,x and z values

    initial begin
       ...     
    end

    ...
  task send();
     send_addrs()?;
     send_pad();
     send_payload();
  endtask: send

  task send_addrs()?;
     ...
  endtask: send_addrs

  task send_pad();?
     ...
  endtask: send_pad
    ...
endprogram:test

8、在发送pad( )任务体中,会驱动frame_n,valid_n和din信号作为每一个路由器的配置(specification)

program automatic test(router_io.TB rtr_io);
    int run for_n packets;    //number of packets to test

    bit[ 3:0] sa;             // source address (input port)
    bit [3:0] da;             // destination address (output port)
    logic[7:0] payload[$];   // packet data array
                        //logic stores 0,1,x and z values

    initial begin
       ...     
    end

    ...
  task send();
     send_addrs()?;
     send_pad();
     send_payload();
  endtask: send

  task send_addrs()?;
     ...
  endtask: send_addrs

  task send_pad();?
        rtr_io.cb.frame_n[sa] <=1'b0 ;
        rtr_io.cb.valid_n[sa] <= 1'b1;
        rtr_io.cb.din [sa] <=1'bl;
        repeat (5)e(rtr_io.cb);
  endtask: send_pad
    ...
endprogram:test

9.创建send_payload(),这个device driver发送payload到路由器中。

program automatic test(router_io.TB rtr_io);
    int run for_n packets;    //number of packets to test

    bit[ 3:0] sa;             // source address (input port)
    bit [3:0] da;             // destination address (output port)
    logic[7:0] payload[$];   // packet data array
                        //logic stores 0,1,x and z values

    initial begin
       ...     
    end

    ...
  task send();
     send_addrs()?;
     send_pad();
     send_payload();
  endtask: send

  task send_addrs()?;
     ...
  endtask: send_addrs

  task send_pad();?
     ...
  endtask: send_pad
  
  task  send_payload();
     ...
  endtask:  send_payload

endprogram:test

10.在send_payload()任务的body中,有如下操作: .

  • 写一个可执行“payload.size()”的次的循环。
  • 这个循环内的payload[$]序列中,每8-bit数据被以一个周期一个bit的速度进行传送。
  • 记着在每次路由器的配置中驱动valid_n。
  • 在每次路由器的配置中,在发送到这个数据包的最后一位时,将frame_n信号反转至1'’ b1.。
  • 当数据包发送完成后,将valid_n信号返回到1’ b1。
program automatic test(router_io.TB rtr_io);
    int run for_n packets;    //number of packets to test

    bit[ 3:0] sa;             // source address (input port)
    bit [3:0] da;             // destination address (output port)
    logic[7:0] payload[$];   // packet data array
                        //logic stores 0,1,x and z values

    initial begin
       ...     
    end

    ...
  task send();
     send_addrs()?;
     send_pad();
     send_payload();
  endtask: send

  task send_addrs()?;
     ...
  endtask: send_addrs

  task send_pad();?
     ...
  endtask: send_pad
  
  task  send_payload();
    foreach (payload[index] ) begin      //队列里面的index不需要定义,也不需要修改
        for(int i=0; i<8; i++) begin
            rtr_io.cb.din[sa] <= payload [index][i];
            rtr_io.cb.valid_n[sa] <= 1'b0 ;
            rtr_io.cb.frame_n[sa]<=(index== (payload.size ()-1)) && (i-=7) ;
            @(rtr_io.cb);
        end
   end
    rtr_io.cb.valid_ n[sa]<=1 "b1 ;

  endtask:  send_payload
endprogram:test

注意:

????????特别注意你是怎样提前触发时钟(advance the clock)。

????????如果在一个子程序中您在退出子程序时提前触发时钟,然后在另一个子程序中您在进入子程序时提前触发时钟,可能会导致错误的计时。

11、保存并关闭test.sv文件

任务四:对program进行编译和纠错(Debug)

任务五:拓展program到可以发送21个数据包

1、修改program模块,使用相同的sa=3和da=7,发送21个数据包。(上面是2-4个)

2、编译(Compile),仿真(Simulate),查看波形。

3、对-sv_seed random的仿真选项的认识

(1) 尝试着多次重新启动仿真,可以使用“restart”命令来重启,再对比连续两次生成的随机数据,看看它们之间是否相同呢?

(2)然后再在仿真器命令行处使用下面命令来加载仿真。

vsim -novopt -solvefaildebug -sv_seed 0 work.router_test_top
//这里我们多传递了两个必须的仿真参数,
//-solvefaildebug是为了调试随机变量的,
//-sv_seed NUM则是为了传递随机的种子。

那么使用这个命令再看,是否与之前没有使用-sv_seed 0的命令产生了相同的数据呢?

(3)最后,请改为使用下面命令再来比较前后两次的数据是否相同呢?

vsim -novopt -solvefaildebug -sv_seed random work.router_test_top

那么.你对-sv_seed random的仿真选项的认识是什么?
?

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-04-30 09:04:54  更:2022-04-30 09:05:10 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 19:42:10-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码