// ========== Copyright Header Begin ========================================== // // OpenSPARC T2 Processor File: siu_dmu_mon.vr // Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved // 4150 Network Circle, Santa Clara, California 95054, U.S.A. // // * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // For the avoidance of doubt, and except that if any non-GPL license // choice is available it will apply instead, Sun elects to use only // the General Public License version 2 (GPLv2) at this time for any // software where a choice of GPL license versions is made // available with the language indicating that GPLv2 or any later version // may be used, or where a choice of which version of the GPL is applied is // otherwise unspecified. // // Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, // CA 95054 USA or visit www.sun.com if you need additional information or // have any questions. // // ========== Copyright Header End ============================================ #include "siumon.if.vrh" #include "siumon_ports_binds.vrh" #include "std_display_class.vrh" #include "siu_dmu_packet.vrh" #include "siu_monitor.vrh" class siu_dmu_monitor { dmumon_port monitor; siu_dmu_packet snd_packet; siu_dmu_packet rec_packet; integer snd_mbox, rec_mbox; StandardDisplay dbg; string myname; task new (dmumon_port monitor, integer snd_mbox, integer rec_mbox, StandardDisplay dbg); task monitor_send (); task monitor_recv (); function integer get_send_pkt(Cycle_Mode mode, integer cycle); function integer check_send(Cycle_Mode mode); function integer get_recv_pkt(Cycle_Mode mode, integer cycle); function integer check_recv(Cycle_Mode mode); } task siu_dmu_monitor::new(dmumon_port monitor, integer snd_mbox, integer rec_mbox, StandardDisplay dbg) { this.monitor = monitor; snd_packet = new(RDD, 0, 0, 0, 1, 1); rec_packet = new(RDD, 0, 0, 0, 1, 1); this.snd_mbox = snd_mbox; this.rec_mbox = rec_mbox; this.dbg = dbg; myname = "siu-dmu"; dbg.dispmon(myname, MON_NORMAL, psprintf ("monitor ready !")); fork { monitor_send(); } join none fork { monitor_recv(); } join none } task siu_dmu_monitor::monitor_send() { siu_dmu_packet packet; integer i, data_cycles; integer fail, result, temp; string t,p,q; while (1) { @(posedge monitor.$clk); if (monitor.$sreq === 1'b1) { data_cycles = 0; fail = 0; temp = 0; // header result = get_send_pkt(HEADER_C, 1); fail = check_send(HEADER_C); case (snd_packet.type) { RDD: { t="R"; p="N"; } WRI: { t="W"; p=(snd_packet.posted) ? "P" : "N"; } WRM: { t="M"; p="P"; } INT: { t="I"; p="N"; } PIORTN: { t="P"; p="N"; } } q = (snd_packet.bypass) ? "bypass" : "order"; dbg.dispmon (myname, MON_NORMAL, psprintf ("snd [%s%s,%4x,%10x] %s ", t, p, snd_packet.id, snd_packet.pa, q)); // data if (monitor.$sdatareq === 1'b1) { data_cycles = 4; if (monitor.$datareq16 === 1'b1) data_cycles = 1; } for (i=0; i siu pkt=%x protocol fail!", snd_packet.id)); else mailbox_put(snd_mbox, packet); } } } task siu_dmu_monitor::monitor_recv() { integer i, result, fail, temp, data_cycles; while (1) { @(posedge monitor.$clk); if (monitor.$rreq === 1'b1) { data_cycles = 0; fail = 0; temp = 0; result = get_recv_pkt(HEADER_C, 1); fail = check_recv(HEADER_C); dbg.dispmon(myname, MON_NORMAL, psprintf ("siu -> dmu pkt=%x ", rec_packet.id)); // data /*if (monitor.$rdatareq === 1'b1)*/ data_cycles = 4; for (i=0; i dmu pkt=%x protocol fail!", snd_packet.id)); else mailbox_put(rec_mbox, rec_packet); } } } function integer siu_dmu_monitor::get_send_pkt(Cycle_Mode mode, integer cycle) { if (mode == HEADER_C) { // bypass snd_packet.bypass = monitor.$bypass; // take header snd_packet.posted = monitor.$sdata[126]; snd_packet.target = monitor.$sdata[123]; snd_packet.id = monitor.$sdata[79:64]; snd_packet.pa = monitor.$sdata[39:0]; snd_packet.tout = monitor.$sdata[82]; snd_packet.ue = monitor.$sdata[81]; snd_packet.uce = monitor.$sdata[80]; // type if (monitor.$sdata[123] === 1'b1) { if (monitor.$sdatareq === 1'b0) snd_packet.type = RDD; else if (monitor.$sdatareq === 1'b1) { if (monitor.$sdata[124] === 1'b1) snd_packet.type = WRM; else snd_packet.type = WRI; } } else { if (monitor.$sdata[127] === 1'b1) snd_packet.type = PIORTN; else snd_packet.type = INT; } } if (mode == DATA_C) { snd_packet.data[cycle*2] = monitor.$sdata[63:0]; snd_packet.be[cycle*2] = monitor.$sdata[3:0]; snd_packet.data[cycle*2+1] = monitor.$sdata[127:64]; snd_packet.be[cycle*2+1] = monitor.$sdata[7:4]; } } function integer siu_dmu_monitor::check_send(Cycle_Mode mode) { integer fail = 0; if (mode == HEADER_C) { // to L2, RDD, WRI and WRM if (monitor.$sdata[123] === 1'b1) { if (monitor.$sdata[122] !== 1'b0 || monitor.$sdata[127] !== 1'b0) { fail++; dbg.dispmon(myname, MON_NORMAL, psprintf ("invalid DMA header")); } if (monitor.$sdatareq === 1'b0 && monitor.$datareq16 === 1'b0) { if (monitor.$sdata[126:125] !== 2'b01 ) { fail++; dbg.dispmon(myname, MON_NORMAL, psprintf ("invalid RDD header")); } } else if (monitor.$sdatareq === 1'b1) { if (monitor.$sdata[125:123] !== 3'b011 && monitor.$sdata[125:123] !== 3'b001 ) { fail++; dbg.dispmon(myname, MON_NORMAL, psprintf ("invalid WRI/WRM header")); } } } // to NCU PIORTN and INT if (monitor.$sdata[122] === 1'b1) { if (monitor.$sdata[123] !== 1'b0) { fail++; dbg.dispmon(myname, MON_NORMAL, psprintf ("invalid non-DMA header")); } if (monitor.$sdata[127] === 1'b1) { if (monitor.$sdata[126:125] !== 2'b01 ) { fail++; dbg.dispmon(myname, MON_NORMAL, psprintf ("invalid PIORTN header")); } } else { if (monitor.$sdata[126:124] !== 3'b000 ) { fail++; dbg.dispmon(myname, MON_NORMAL, psprintf ("invalid INT header")); } } } // comment out and change later /* if (monitor.$sdata[121:83] !== 39'b0 || monitor.$sdata[63:40] !== 24'b0) { fail++; dbg.dispmon(myname, MON_NORMAL, psprintf ("header error, reserved bits not zero")); } */ } if (mode == DATA_C) { if (monitor.$sreq === 1'b1 || monitor.$sdatareq === 1'b1 || monitor.$datareq16 === 1'b1) { fail++; dbg.dispmon(myname, MON_NORMAL, psprintf ("req error, active in data cycles")); } } check_send = fail; } function integer siu_dmu_monitor::get_recv_pkt(Cycle_Mode mode, integer cycle) { if (mode == HEADER_C) { // take header rec_packet.posted = monitor.$rdata[126]; rec_packet.id = monitor.$rdata[79:64]; rec_packet.pa = monitor.$rdata[39:0]; rec_packet.tout = monitor.$rdata[82]; rec_packet.ue = monitor.$rdata[81]; rec_packet.uce = monitor.$rdata[80]; // type, changed somePerson as only RDD type is valid /*if (monitor.$rdatareq === 1'b0) rec_packet.type = WRI; else if (monitor.$rdatareq === 1'b1)*/ rec_packet.type = RDD; } if (mode == DATA_C) { rec_packet.data[cycle*2] = monitor.$rdata[63:0]; rec_packet.data[cycle*2+1] = monitor.$rdata[127:64]; } } function integer siu_dmu_monitor::check_recv(Cycle_Mode mode) { integer fail = 0; if (mode == HEADER_C) { /*if (monitor.$rdatareq === 1'b0) { if (monitor.$rdata[127:122] !== 6'b100010) { fail++; dbg.dispmon(myname, MON_NORMAL, psprintf ("invalid WRI ack header")); } } if (monitor.$rdatareq === 1'b1) {*/ if (monitor.$rdata[127:122] !== 6'b101010) { fail++; dbg.dispmon(myname, MON_NORMAL, psprintf ("invalid RDD rtn header")); } //} if (monitor.$rdata[121:83] !== 39'b0 || monitor.$rdata[63:62] !== 2'b0 || monitor.$rdata[55:40] !== 16'b0) { fail++; dbg.dispmon(myname, MON_NORMAL, psprintf ("header error, reserved bits not zero")); } } if (mode == DATA_C) { if (monitor.$rreq === 1) // || monitor.$rdatareq === 1) { // Fu: 7/20/04 need document in the spec. //fail++; dbg.dispmon(myname, MON_WARN, psprintf ("req error, active in data cycles")); } } check_recv = fail; }