Vengineerの妄想(準備期間)

人生は短いけど、長いです。人生を楽しみましょう!

Xilinx Vitis の中を調べる(その9)

はじめに

Xilinx Vitis の中を調べるのその9。

今回は、sv_module_top をみていきます。

sv_module_top

svtb/sv_module_top.sv は、下記のようになっています。

//==============================================================
//Vitis HLS - High-Level Synthesis from C, C++ and OpenCL v2022.1 (64-bit)
//Tool Version Limit: 2022.04
//Copyright 1986-2022 Xilinx, Inc. All Rights Reserved.
//==============================================================

`ifndef SV_MODULE_TOP_SV
`define SV_MODULE_TOP_SV


`timescale 1ns/1ps


`include "uvm_macros.svh"
import uvm_pkg::*;
import file_agent_pkg::*;
import svr_pkg::*;
import multi_apuint_subsystem_pkg::*;
`include "multi_apuint_subsys_test_sequence_lib.sv"
`include "multi_apuint_test_lib.sv"


module sv_module_top;


    misc_interface              misc_if ( .clock(apatb_multi_apuint_top.AESL_clock), .reset(apatb_multi_apuint_top.AESL_
reset) );
    assign apatb_multi_apuint_top.ap_start = misc_if.tb2dut_ap_start;
    assign misc_if.dut2tb_ap_done = apatb_multi_apuint_top.ap_done;
    assign misc_if.dut2tb_ap_ready = apatb_multi_apuint_top.ap_ready;
    initial begin
        uvm_config_db #(virtual misc_interface)::set(null, "uvm_test_top.top_env.*", "misc_if", misc_if);
    end


    svr_if #(8)  svr_multi_in0_if    (.clk  (apatb_multi_apuint_top.AESL_clock), .rst(apatb_multi_apuint_top.AESL_reset)
);
    assign apatb_multi_apuint_top.multi_in0_ap_vld = svr_multi_in0_if.valid;
    assign svr_multi_in0_if.ready = apatb_multi_apuint_top.multi_in0_ap_ack;
    assign apatb_multi_apuint_top.multi_in0 = svr_multi_in0_if.data[7:0];
    initial begin
        uvm_config_db #( virtual svr_if#(8) )::set(null, "uvm_test_top.top_env.env_master_svr_multi_in0.*", "vif", svr_m
ulti_in0_if);
    end


    svr_if #(8)  svr_multi_in1_if    (.clk  (apatb_multi_apuint_top.AESL_clock), .rst(apatb_multi_apuint_top.AESL_reset)
);
    assign apatb_multi_apuint_top.multi_in1_ap_vld = svr_multi_in1_if.valid;
    assign svr_multi_in1_if.ready = apatb_multi_apuint_top.multi_in1_ap_ack;
    assign apatb_multi_apuint_top.multi_in1 = svr_multi_in1_if.data[7:0];
    initial begin
        uvm_config_db #( virtual svr_if#(8) )::set(null, "uvm_test_top.top_env.env_master_svr_multi_in1.*", "vif", svr_m
ulti_in1_if);
    end


    svr_if #(16)  svr_multi_out_if    (.clk  (apatb_multi_apuint_top.AESL_clock), .rst(apatb_multi_apuint_top.AESL_reset
));
    assign svr_multi_out_if.valid = apatb_multi_apuint_top.multi_out_ap_vld;
    assign apatb_multi_apuint_top.multi_out_ap_ack = svr_multi_out_if.ready;
    assign svr_multi_out_if.data[15:0] = apatb_multi_apuint_top.multi_out;
    initial begin
        uvm_config_db #( virtual svr_if#(16) )::set(null, "uvm_test_top.top_env.env_slave_svr_multi_out.*", "vif", svr_m
ulti_out_if);
    end


    initial begin
        run_test();
    end
endmodule
`endif

sv_module_top は、svtb/sv_module_top.sv です。下図のような構成になっています。sv_module_top モジュールには、下記の4つの interface を使って、トップテストベンチ内の信号に接続しています。

  • svr_if svr_multi_in0_if
  • svr_if svr_multi_in1_if
  • svr_if svr_multi_out_if
  • misc_interface misc_if

  • misc_interface は、ap_xxx 関連
  • svr_if #(8) svr_multi_in0_if は、入力信号 (multi_in0) 関連
  • svr_if #(8) svr_multi_in1_if は、入力信号 (multi_in1) 関連
  • svr_if #(16) svr_multi_out_if は、出力信号 (multi_out) 関連

です。

initial 文の中で、uvm_config db にて、"uvm_test_top.top_env” の "misc_if" に、misc_if を設定しています。

    initial begin
        uvm_config_db #(virtual misc_interface)::set(null, "uvm_test_top.top_env.*", "misc_if", misc_if);
    end

misc_interface は、svtb/misc_interface.sv です。下記のようなコードになっています。

//==============================================================
//Vitis HLS - High-Level Synthesis from C, C++ and OpenCL v2022.1 (64-bit)
//Tool Version Limit: 2022.04
//Copyright 1986-2022 Xilinx, Inc. All Rights Reserved.
//==============================================================
`ifndef MISC_INTERFACE__SV
`define MISC_INTERFACE__SV
`timescale 1ns/1ps
interface misc_interface (input clock, input reset);


    logic    dut2tb_ap_done   ;
    logic    dut2tb_ap_idle   ;
    logic    dut2tb_ap_ready  ;
    logic    tb2dut_ap_start  = 0;
    logic    tb2dut_ap_continue = 0;
    logic    ap_ready_for_nexttrans = 0;
    logic    ap_done_for_nexttrans = 0;
    logic    initialed = 0;
    logic    finished = 0;
    event    dut2tb_ap_ready_evt;
    event    dut2tb_ap_done_evt;
    event    initialed_evt;
    event    finished_evt;


    clocking pclk @(posedge clock);
        default input #0.1ns output #0.1ns;
    endclocking


    clocking nclk @(negedge clock);
        default input #0.1ns output #0.1ns;
    endclocking


endinterface
`endif

initial 文の中で、uvm_config db にて、"uvm_test_top.top_env.env_master_svr_multi_in0” / "uvm_test_top.top_env.env_master_svr_multi_in1” / "uvm_test_top.top_env.env_slave_svr_multi_out." の "vif" に、svr_multi_in1_if を設定しています。

    initial begin
        uvm_config_db #( virtual svr_if#(8) )::set(null, "uvm_test_top.top_env.env_master_svr_multi_in0.*", "vif", svr_multi_in0_if);
    end
    initial begin
        uvm_config_db #( virtual svr_if#(8) )::set(null, "uvm_test_top.top_env.env_master_svr_multi_in1.*", "vif", svr_multi_in1_if);
    end
    initial begin
        uvm_config_db #( virtual svr_if#(16) )::set(null, "uvm_test_top.top_env.env_slave_svr_multi_out.*", "vif", svr_multi_out_if);
    end

svr_if# は、svr/svr_if.sv です。下記のようなコードになっています。

//==============================================================
//Vitis HLS - High-Level Synthesis from C, C++ and OpenCL v2022.1 (64-bit)
//Tool Version Limit: 2022.04
//Copyright 1986-2022 Xilinx, Inc. All Rights Reserved.
//==============================================================
`ifndef SVR_IF__SV
    `define SVR_IF__SV

    interface svr_if#(int DATA_WIDTH = 32)(input clk, input rst);

        logic [DATA_WIDTH -1: 0] data ;
        logic                    valid;
        logic                    ready;

        property noxwhenh(logic x, logic y);
            disable iff(!rst)
                @(posedge clk)
                (x&y)===1'b0 | (x===1'b1 && (y===1'b0|y==='h1)) | (y==='b1 && (x===1'b0|x==='b1));
        endproperty

        property nodatax(logic x, logic y, logic [DATA_WIDTH - 1: 0] data);
            disable iff(!rst)
                @(posedge clk)
                (x&y)===1'b0 | ((x === 1'b1) && (y === 1'b1) && (|data === 1'b0) | (|data === 1'b1)) | (x === 1'bx) | (y
 === 1'bx);
        endproperty

        validh_readxy: assert property(noxwhenh(valid, ready))
            else $warning("invalid X state when valid/ready is asserted time:%0t  valid:%0d, ready:%0d", $time, valid, r
eady);

        validh_data: assert property(nodatax(valid, ready, data))
            else $warning("data is in X state when valid and ready are asserted time:%0t", $time);

        stable_when_valid: assert property(
                    @(posedge clk) disable iff(!rst)
                    ready===1'b0 && $rose(valid) | ($fell(ready) && valid===1'b1) | ($fell(ready) && $rose(valid)) |=>
                    ($stable(data) [*0:$] ##1 ready===1'b1 & $stable(data)) or (ready===1'b1 & $stable(data))
                )
            else $warning("data is not stable when valid is asserted time:%0t", $time);
    endinterface

`endif

おわりに

次回は、uvm_test_top.top_env についてみてみます。