📄 tb_env.sv
字号:
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 + -