📄 master.sv
字号:
// // -------------------------------------------------------------// Copyright 2004-2008 Synopsys, Inc.// All Rights Reserved Worldwide// // Licensed under the Apache License, Version 2.0 (the// "License"); you may not use this file except in// compliance with the License. You may obtain a copy of// the License at// // http://www.apache.org/licenses/LICENSE-2.0// // Unless required by applicable law or agreed to in// writing, software distributed under the License is// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR// CONDITIONS OF ANY KIND, either express or implied. See// the License for the specific language governing// permissions and limitations under the License.// -------------------------------------------------------------// typedef class wb_master; virtual class wb_master_callbacks extends vmm_xactor_callbacks; virtual task pre_cycle(wb_master xactor, wb_cycle cycle, ref bit drop); endtask virtual task post_cycle(wb_master xactor, /*const*/ wb_cycle cycle); endtaskendclass: wb_master_callbacks class wb_master extends vmm_xactor; virtual wb_if.master sigs; wb_cycle_channel exec_chan; local wb_cfg cfg; local wb_cfg hard_rst_cfg; extern function new(string instance, int unsigned stream_id, wb_cfg cfg, virtual wb_if.master sigs, wb_cycle_channel exec_chan = null); extern virtual function void reconfigure(wb_cfg cfg); extern virtual function void reset_xactor(reset_e typ = SOFT_RST); extern protected virtual task main(); // Example 4-30 extern protected virtual task read(input bit [63:0] addr, output bit [63:0] data, input bit [ 7:0] sel, input bit [15:0] tgc, input bit [15:0] tga, output bit [15:0] tgd, input bit lock, output wb_cycle::status_e status); extern protected virtual task write(input bit [63:0] addr, input bit [63:0] data, input bit [ 7:0] sel, input bit [15:0] tgc, input bit [15:0] tga, input bit [15:0] tgd, input bit lock, output wb_cycle::status_e status);endclass: wb_masterfunction wb_master::new(string instance, int unsigned stream_id, wb_cfg cfg, virtual wb_if.master sigs, wb_cycle_channel exec_chan); super.new("Wishbone Master", instance, stream_id); this.cfg = cfg; this.hard_rst_cfg = cfg; this.sigs = sigs; if (exec_chan == null) exec_chan = new("Wishbone Master Execution Channel", instance); this.exec_chan = exec_chan; this.log.is_above(this.exec_chan.log); // In-order, blocking execution model this.exec_chan.reconfigure(1, 0);endfunction: new function void wb_master::reconfigure(wb_cfg cfg); this.cfg = cfg;endfunction: reconfigurefunction void wb_master::reset_xactor(reset_e typ); super.reset_xactor(typ); this.sigs.mck.wdat <= 'bz; this.sigs.mck.wtgd <= 'bz; this.sigs.mck.adr <= 'bz; this.sigs.mck.we <= 'bz; this.sigs.mck.cyc <= 'bz; this.sigs.mck.lock <= 'bz; this.sigs.mck.sel <= 'bz; this.sigs.mck.stb <= 'bz; this.sigs.mck.tga <= 'bz; this.sigs.mck.tgc <= 'bz; this.sigs.mck.cti <= 'bz; this.sigs.mck.bte <= 'bz; this.exec_chan.flush(); if (typ >= HARD_RST) begin this.cfg = this.hard_rst_cfg; endendfunction: reset_xactortask wb_master::main(); fork super.main(); join_none forever begin wb_cycle tr; bit drop = 0; this.sigs.mck.wdat <= 'bz; this.sigs.mck.wtgd <= 'bz; this.sigs.mck.adr <= 'bz; this.sigs.mck.cyc <= 'bz; this.sigs.mck.lock <= 'bz; this.sigs.mck.sel <= 'bz; this.sigs.mck.stb <= 'bz; this.sigs.mck.tga <= 'bz; this.sigs.mck.tgc <= 'bz; this.sigs.mck.cti <= 'bz; this.sigs.mck.bte <= 'bz; this.wait_if_stopped_or_empty(this.exec_chan); this.exec_chan.activate(tr); tr.status = wb_cycle::UNKNOWN ; `vmm_callback(wb_master_callbacks, pre_cycle(this, tr, drop)); if (drop) begin this.exec_chan.remove(); continue; end if (tr.next_cycle !== wb_cycle::CLASSIC || (tr.kind !== wb_cycle::READ && tr.kind != wb_cycle::WRITE )) begin `vmm_error(this.log, "Only single read/write classic cycles are supported"); this.exec_chan.remove(); continue; end this.exec_chan.start(); case (tr.kind) wb_cycle::READ : this.read(tr.addr, tr.data, tr.sel, tr.tgc, tr.tga, tr.tgd, tr.lock, tr.status); wb_cycle::WRITE : this.write(tr.addr, tr.data, tr.sel, tr.tgc, tr.tga, tr.tgd, tr.lock, tr.status); endcase this.exec_chan.complete(); `vmm_trace(this.log, tr.psdisplay("Completed: ")); `vmm_callback(wb_master_callbacks, post_cycle(this, tr)); this.exec_chan.remove(); endendtask: maintask wb_master::read(input bit [63:0] addr, output bit [63:0] data, input bit [ 7:0] sel, input bit [15:0] tgc, input bit [15:0] tga, output bit [15:0] tgd, input bit lock, output wb_cycle::status_e status); // Section 3.2.1 of Wishbone B3 Specification @(this.sigs.mck); // Edge 0 this.sigs.mck.adr <= addr; this.sigs.mck.tga <= tga; this.sigs.mck.we <= 1'b0; this.sigs.mck.sel <= sel; this.sigs.mck.cyc <= 1'b1; this.sigs.mck.tgc <= tgc; this.sigs.mck.stb <= 1'b1; // Edge 1 status = wb_cycle::TIMEOUT ; repeat (this.cfg.max_n_wss + 1) begin // Wait states @(this.sigs.mck); case (1'b1) this.sigs.mck.err: status = wb_cycle::ERR ; this.sigs.mck.rty: status = wb_cycle::RTY ; this.sigs.mck.ack: status = wb_cycle::ACK ; default: continue; endcase break; end if (status == wb_cycle::TIMEOUT ) begin `vmm_error(this.log, "Timeout waiting for ACK_I, RTY_I or ERR_I"); end data = this.sigs.mck.rdat; tgd = this.sigs.mck.rtgd; this.sigs.mck.lock <= lock; this.sigs.mck.cyc <= lock;endtask: readtask wb_master::write(input bit [63:0] addr, input bit [63:0] data, input bit [ 7:0] sel, input bit [15:0] tgc, input bit [15:0] tga, input bit [15:0] tgd, input bit lock, output wb_cycle::status_e status); // Section 3.2.2 of Wishbone B3 Specification @(this.sigs.mck); // Edge 0 this.sigs.mck.adr <= addr; this.sigs.mck.tga <= tga; this.sigs.mck.wdat <= data; this.sigs.mck.wtgd <= tgd; this.sigs.mck.we <= 1'b1; this.sigs.mck.sel <= sel; this.sigs.mck.cyc <= 1'b1; this.sigs.mck.tgc <= tgc; this.sigs.mck.stb <= 1'b1; // Edge 1 status = wb_cycle::TIMEOUT ; repeat (this.cfg.max_n_wss + 1) begin // Wait states @(this.sigs.mck); case (1'b1) this.sigs.mck.err: status = wb_cycle::ERR ; this.sigs.mck.rty: status = wb_cycle::RTY ; this.sigs.mck.ack: status = wb_cycle::ACK ; default: continue; endcase break; end if (status == wb_cycle::TIMEOUT ) begin `vmm_error(this.log, "Timeout waiting for ACK_I, RTY_I or ERR_I"); end this.sigs.mck.lock <= lock; this.sigs.mck.cyc <= lock;endtask: write
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -