⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tb_env.sv

📁 VMM 文档加源码, synopsys公司很好的验证资料
💻 SV
📖 第 1 页 / 共 3 页
字号:
      this.cfg.wb.max_addr = 32'hFFFF_FFFF;      this.cfg.wb.min_addr = 32'h0000_0000;      this.cfg.wb.max_addr.rand_mode(0);      this.cfg.wb.min_addr.rand_mode(0);      if (!this.cfg.randomize()) begin         `vmm_fatal(log, "Failed to randomize test configuration");      end   endfunction: gen_cfg   // Example 4-19   virtual function void build();      // Example 4-63      annotated_eth_frame ann_fr = new;      super.build();      `vmm_note(this.log, this.cfg.psdisplay());      fork         tb_top.mii.mii_FullDuplex    <= this.cfg.mii.full_duplex;      join_none      // Example 5-47      this.sb = new(this.cfg);      this.phy_src = new("Phy Side", 0);      this.phy_src.stop_after_n_insts = this.cfg.run_for_n_rx_frames;      this.mac = new("PHY Side", 0, this.cfg.mac,                     this.phy_src.out_chan);      // Example 4-63      ann_fr = new;      ann_fr.direction = "MAC->PHY";      // Example 4-13      this.phy = new("PHY Side", 0, this.cfg.mii,                     tb_top.mii.phy_layer,                     this.mac.pls_tx_chan,                     this.mac.pls_rx_chan,                     this.mac.indications,                     ann_fr);      this.mon = new("Passive", 0, this.cfg.mii, tb_top.mii.passive);      this.mon.to_mac_chan.sink();      this.mon.to_phy_chan.sink();      this.host = new("Host", 1, this.cfg.wb, tb_top.wb_sl);      begin         wb_cycle_resp_no_wss no_wss_resp = new(null, this.cfg.wb);         this.ram  = new("RAM",  1, null, null, no_wss_resp);      end      this.slv  = new("Slave",  1, this.cfg.wb, tb_top.wb_ma,                      this.ram.req_chan, this.ram.resp_chan);      this.swem = new("SW", 1, this.cfg, this.sb, this.host, this.ram);      this.host_src = new("Host Side", 1, this.swem.tx_chan);      this.host_src.stop_after_n_insts = this.cfg.run_for_n_tx_frames;      // Host BFM needed right away to configure DUT      this.host.start_xactor();      // Integrate scoreboard      // Example 4-21      // Example 5-53      begin         sb_mac_cbs cb = new(this.sb);         this.mac.append_callback(cb);      end      // Example 5-54      fork         forever begin            eth_frame fr;            this.mac.rx_chan.get(fr);            this.sb.received_by_phy_side(fr);         end      join_none//      this.phy.log.set_verbosity(vmm_log::DEBUG_SEV ,);//      this.mac.log.set_verbosity(vmm_log::DEBUG_SEV ,);//      this.log.set_verbosity(vmm_log::TRACE_SEV ,);//      this.swem.log.set_verbosity(vmm_log::TRACE_SEV ,);//      this.host.log.set_verbosity(vmm_log::TRACE_SEV ,);//      this.slv.log.set_verbosity(vmm_log::DEBUG_SEV ,);//      this.ram.log.set_verbosity(vmm_log::DEBUG_SEV ,);      this.log.disable_types(vmm_log::INTERNAL_TYP , "/./", "/./");   endfunction: build   virtual task reset_dut();      super.reset_dut();      tb_top.tx_rx_offset <= this.cfg.tx_rx_clk_offset;      tb_top.mii_100Mb    <= ~this.cfg.mii.is_10Mb;      tb_top_env.reset();   endtask: reset_dut         virtual task cfg_dut();      bit [31:0] val;      wb_cycle   cyc = new(this.cfg.wb);      bit        ok;      super.cfg_dut();      // Interpret the configuration descriptor and program the      // DUT accordingly      // MODER      val = 17'b1_1110_0000_0100_0000;      val[14] = this.cfg.huge_enable;      val[10] = this.cfg.mac.full_duplex;      val[5] = this.cfg.mac.promiscuous;      ok = cyc.randomize() with {kind == wb_cycle::WRITE;                                 addr == 32'h0000_0000;                                 data == val;                                 sel  == 4'hF;};      if (!ok) begin         `vmm_fatal(this.log, "Unable to create WRITE cycle to MODER");      end      this.host.exec_chan.put(cyc);      if (cyc.status !== wb_cycle::ACK) begin         `vmm_error(this.log, "Unable to write to MODER");      end      // INT_MASK      val = 32'h0000_000F;      ok = cyc.randomize() with {kind == wb_cycle::WRITE;                                 addr == 32'h0000_0008;                                 data == val;                                 sel  == 4'hF;};      if (!ok) begin         `vmm_fatal(this.log, "Unable to create WRITE cycle to INT_MASK");      end      this.host.exec_chan.put(cyc);      if (cyc.status !== wb_cycle::ACK) begin         `vmm_error(this.log, "Unable to write to INT_MASK");      end      // IPGT      val = (this.cfg.mac.full_duplex) ? 16'h15 : 16'h12;      ok = cyc.randomize() with {kind == wb_cycle::WRITE;                                 addr == 32'h0000_000C;                                 data == val;                                 sel  == 4'hF;};      if (!ok) begin         `vmm_fatal(this.log, "Unable to create WRITE cycle to IPGT");      end      this.host.exec_chan.put(cyc);      if (cyc.status !== wb_cycle::ACK) begin         `vmm_error(this.log, "Unable to write to INT_IPGT");      end      // PACKETLEN      val = {16'h000F, this.cfg.max_frame_len};      ok = cyc.randomize() with {kind == wb_cycle::WRITE;                                 addr == 32'h0000_0018;                                 data == val;                                 sel  == 4'hF;};      if (!ok) begin         `vmm_fatal(this.log, "Unable to create WRITE cycle to PACKETLEN");      end      this.host.exec_chan.put(cyc);      if (cyc.status !== wb_cycle::ACK) begin         `vmm_error(this.log, "Unable to write to PACKETLEN");      end      // TX_BD_NUM      val = this.cfg.rx_bd_offset;      ok = cyc.randomize() with {kind == wb_cycle::WRITE;                                 addr == 32'h0000_0020;                                 data == val;                                 sel  == 4'hF;};      if (!ok) begin         `vmm_fatal(this.log, "Unable to create WRITE cycle to TX_BD_NUM");      end      this.host.exec_chan.put(cyc);      if (cyc.status !== wb_cycle::ACK) begin         `vmm_error(this.log, "Unable to write to TX_BD_NUM");      end      // CTRLMODER      val = 32'b0111;      ok = cyc.randomize() with {kind == wb_cycle::WRITE;                                 addr == 32'h0000_0024;                                 data == val;                                 sel  == 4'hF;};      if (!ok) begin         `vmm_fatal(this.log, "Unable to create WRITE cycle to CTRLMODER");      end      this.host.exec_chan.put(cyc);      if (cyc.status !== wb_cycle::ACK) begin         `vmm_error(this.log, "Unable to write to CTRLMODER");      end      // MAC_ADDR0      val = this.cfg.dut_addr[31:0];      ok = cyc.randomize() with {kind == wb_cycle::WRITE;                                 addr == 32'h0000_0040;                                 data == val;                                 sel  == 4'hF;};      if (!ok) begin         `vmm_fatal(this.log, "Unable to create WRITE cycle to MAC_ADDR0");      end      this.host.exec_chan.put(cyc);      if (cyc.status !== wb_cycle::ACK) begin         `vmm_error(this.log, "Unable to write to MAC_ADDR0");      end      // MAC_ADDR1      val = {16'h0000,             this.cfg.dut_addr[47:32]};      ok = cyc.randomize() with {kind == wb_cycle::WRITE;                                 addr == 32'h0000_0044;                                 data == val;                                 sel  == 4'hF;};      if (!ok) begin         `vmm_fatal(this.log, "Unable to create WRITE cycle to MAC_ADDR1");      end      this.host.exec_chan.put(cyc);      if (cyc.status !== wb_cycle::ACK) begin         `vmm_error(this.log, "Unable to write to MAC_ADDR1");      end      // Example 5-22      // Example 5-36      // Make sure the frame generators generate frames with the      // correct DA & SA      this.host_src.randomized_obj.dst = this.cfg.mac.addr;      this.host_src.randomized_obj.dst.rand_mode(0);      this.host_src.randomized_obj.src = this.cfg.dut_addr;      this.host_src.randomized_obj.src.rand_mode(0);      // Example 5-37      begin         dut_eth_frame fr = new(this.cfg);         this.phy_src.randomized_obj = fr;      end      // Initialize the required number of buffer descriptors      begin         bit [31:0] bd_addr;         integer i;         // Tx BD         bd_addr = 32'h0000_0400;         `vmm_trace(this.log, $psprintf("Configuring %0d TxBD starting at 32'h%h",                                        this.cfg.n_tx_bd, bd_addr));         for (i = this.cfg.n_tx_bd; i > 0; i--) begin            val = 32'h0000_4000;            if (i == 1) val[13] = 1'b1;            ok = cyc.randomize() with {kind == wb_cycle::WRITE;                                       addr == bd_addr;                                       data == val;                                       sel  == 4'hF;};            if (!ok) begin               `vmm_fatal(this.log, "Unable to create WRITE cycle to TxBD");            end            this.host.exec_chan.put(cyc);            if (cyc.status !== wb_cycle::ACK) begin               `vmm_error(this.log, "Unable to write to TxBD");            end            val = this.cfg.txrx_bfr_base + i * ((this.cfg.huge_enable) ? 65536 : this.cfg.max_frame_len);            this.cfg.txrx_pnt[bd_addr] = val;            bd_addr += 4; // Buffer pointer            ok = cyc.randomize() with {kind == wb_cycle::WRITE;                                       addr == bd_addr;                                       data == val;                                       sel  == 4'hF;};//$write("***bd_addr=%h, addr=%h (%b) val=%h, data=%h (%b)\n", bd_addr, cyc.addr, (cyc.addr == bd_addr),//       val, cyc.data, cyc.data == val);            if (!ok) begin               `vmm_fatal(this.log, "Unable to create WRITE cycle to TxBD.TxPNT");            end            this.host.exec_chan.put(cyc);            if (cyc.status !== wb_cycle::ACK) begin               // Example 4-26               `vmm_error(this.log, "Unable to write to TxBD.TxPNT");            end            bd_addr += 4;            `vmm_debug(this.log, $psprintf("TxBD #%0d points to 'h%h", i, val));         end         // Rx BD         bd_addr = 32'h0000_0400 + this.cfg.rx_bd_offset * 8;         `vmm_trace(this.log, $psprintf("Configuring %0d RxBD starting at 32'h%h",                                        this.cfg.n_rx_bd, bd_addr));         this.swem.next_rxbd = bd_addr;         for (i = this.cfg.n_rx_bd; i > 0; i--) begin            val = 32'h0000_0000;            val[15] = 1; // Empty            val[14] = 1; // Generate an interrupt            if (i == 1) val[13] = 1'b1;  // Last buffer?            ok = cyc.randomize() with {kind == wb_cycle::WRITE;                                       addr == bd_addr;                                       data == val;                                       sel  == 4'hF;};            if (!ok) begin               `vmm_fatal(this.log, "Unable to create WRITE cycle to RxBD");            end            this.host.exec_chan.put(cyc);            if (cyc.status !== wb_cycle::ACK) begin               `vmm_error(this.log, "Unable to write to RxBD");            end            val = this.cfg.txrx_bfr_base + (this.cfg.n_tx_bd + i) *                   ((this.cfg.huge_enable) ? 65536 : this.cfg.max_frame_len);            this.cfg.txrx_pnt[bd_addr] = val;            bd_addr += 4; // Buffer pointer            ok = cyc.randomize() with {kind == wb_cycle::WRITE;                                       addr == bd_addr;                                       data == val;                                       sel  == 4'hF;};            if (!ok) begin               `vmm_fatal(this.log, "Unable to create WRITE cycle to RxBD.RxPNT");            end            this.host.exec_chan.put(cyc);            if (cyc.status !== wb_cycle::ACK) begin               `vmm_error(this.log, "Unable to write to RxBD.RxPNT");            end            bd_addr += 4; // Next BD            `vmm_debug(this.log, $psprintf("RxBD #%0d points to 'h%h", i, val));         end      end      // Enable Tx & Rx      `vmm_trace(this.log, "Enabling Tx/Rx paths...");      ok = cyc.randomize() with {kind == wb_cycle::READ;                                 addr == 32'h0000_0000;                                 sel  == 4'hF;};      if (!ok) begin         `vmm_fatal(this.log, "Unable to create READ cycle to MODER");      end      this.host.exec_chan.put(cyc);      if (cyc.status !== wb_cycle::ACK) begin         `vmm_error(this.log, "Unable to read from MODER");      end      val = cyc.data;      val[1:0] = 2'b11;      ok = cyc.randomize() with {kind == wb_cycle::WRITE;                                 addr == 32'h0000_0000;                                 data == val;                                 sel  == 4'hF;};      if (!ok) begin         `vmm_fatal(this.log, "Unable to create WRITE cycle to MODER");      end      this.host.exec_chan.put(cyc);      if (cyc.status !== wb_cycle::ACK) begin         `vmm_error(this.log, "Unable to write to MODER");      end   endtask: cfg_dut   // Example 4-22   virtual task start();      super.start();      if (this.cfg.run_for_n_tx_frames > 0) this.host_src.start_xactor();      if (this.cfg.run_for_n_rx_frames > 0) this.phy_src.start_xactor();      this.mac.start_xactor();      // Example 4-13      this.phy.start_xactor();      this.slv.start_xactor();      this.ram.start_xactor();      this.swem.start_xactor();   endtask: start   // Example 4-17   virtual task wait_for_end();      super.wait_for_end();      // Example 4-24      fork         @ (this.end_test) disable wait_for_end;      join_none      // Example 4-23      wait (this.cfg.run_for_n_tx_frames == 0 &&            this.cfg.run_for_n_rx_frames == 0);      disable fork;   endtask: wait_for_end   virtual task stop();      super.stop();      this.host_src.stop_xactor();      this.phy_src.stop_xactor();            // Let the system drain of all in-flight frames      // ToDo...   endtask: stop   virtual task cleanup();      super.cleanup();   endtask: cleanupendclass

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -