// ========== Copyright Header Begin ========================================== // // OpenSPARC T2 Processor File: niu_intr_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 #include "neptune_defines.vri" #include "cMesg.vrh" // If NIU_GATE consider this a blank file #ifdef NIU_GATE // Do nothing #else #include "niu_intr_mon.if.vri" #define TIME {get_time(HI), get_time(LO)} #define TRUE 1 #define FALSE 0 #define ASSERTED 1 #define ASSERTED_LOW 0 #define DEASSERTED 0 #define DEASSERTED_LOW 1 extern Mesg be_msg; class CNiuIntMonitor { string name = "Intr_Mon"; int_mon_port int_monitor; integer INT_MON_ON=0; integer int_active_rel_ovrlap = 0; integer int_active_rel_ibusy_ovrlap = 0; integer activate_ig_sm_after_ibusy = 0; integer activate_ig_sm_during_ibusy = 0; integer ibusy_after_activate_ig_sm = 0; integer ibusy_during_activate_ig_sm = 0; integer ibusy_hi_within_actv = 0; integer actv_asserts_during_ibusy = 0; integer intr_rel_group0 = 0; integer intr_rel_group16 = 0; integer intr_rel_group32 = 0; integer intr_rel_group48 = 0; integer intr_rel_othergrp = 0; integer group0_intr_rel_after_ibusy = 0; integer group16_intr_rel_after_ibusy = 0; integer group32_intr_rel_after_ibusy = 0; integer group48_intr_rel_after_ibusy = 0; integer activate_ig_sm_trigger = 0; integer ibusy_trigger = 0; integer latch_rel_info = 0; coverage_group req_rel_hit_skew0_noibusy_cov { sample_event = @(int_monitor.$req_rel_hit_skew0_noibusy); sample int_monitor.$req_rel_hit_skew0_noibusy { state req_rel_hit_skew0_noibusy(0:1) if (int_monitor.$req_rel_hit_skew0_noibusy == 1); } } coverage_group req_rel_hit_skew1_noibusy_cov { sample_event = @(int_monitor.$req_rel_hit_skew1_noibusy); sample int_monitor.$req_rel_hit_skew1_noibusy { state req_rel_hit_skew1_noibusy(0:1) if (int_monitor.$req_rel_hit_skew1_noibusy == 1); } } coverage_group req_rel_hit_skew2_noibusy_cov { sample_event = @(int_monitor.$req_rel_hit_skew2_noibusy); sample int_monitor.$req_rel_hit_skew2_noibusy { state req_rel_hit_skew2_noibusy(0:1) if (int_monitor.$req_rel_hit_skew2_noibusy == 1); } } coverage_group req_rel_hit_skew3_noibusy_cov { sample_event = @(int_monitor.$req_rel_hit_skew3_noibusy); sample int_monitor.$req_rel_hit_skew3_noibusy { state req_rel_hit_skew3_noibusy(0:1) if (int_monitor.$req_rel_hit_skew3_noibusy == 1); } } coverage_group req_rel_hit_skew4_noibusy_cov { sample_event = @(int_monitor.$req_rel_hit_skew4_noibusy); sample int_monitor.$req_rel_hit_skew4_noibusy { state req_rel_hit_skew4_noibusy(0:1) if (int_monitor.$req_rel_hit_skew4_noibusy == 1); } } coverage_group req_rel_hit_skew5_noibusy_cov { sample_event = @(int_monitor.$req_rel_hit_skew5_noibusy); sample int_monitor.$req_rel_hit_skew5_noibusy { state req_rel_hit_skew5_noibusy(0:1) if (int_monitor.$req_rel_hit_skew5_noibusy == 1); } } coverage_group req_rel_hit_skew0_ibusy_cov { sample_event = @(int_monitor.$req_rel_hit_skew0_ibusy); sample int_monitor.$req_rel_hit_skew0_ibusy { state req_rel_hit_skew0_ibusy(0:1) if (int_monitor.$req_rel_hit_skew0_ibusy == 1); } } coverage_group req_rel_hit_skew1_ibusy_cov { sample_event = @(int_monitor.$req_rel_hit_skew1_ibusy); sample int_monitor.$req_rel_hit_skew1_ibusy { state req_rel_hit_skew1_ibusy(0:1) if (int_monitor.$req_rel_hit_skew1_ibusy == 1); } } coverage_group req_rel_hit_skew2_ibusy_cov { sample_event = @(int_monitor.$req_rel_hit_skew2_ibusy); sample int_monitor.$req_rel_hit_skew2_ibusy { state req_rel_hit_skew2_ibusy(0:1) if (int_monitor.$req_rel_hit_skew2_ibusy == 1); } } coverage_group req_rel_hit_skew3_ibusy_cov { sample_event = @(int_monitor.$req_rel_hit_skew3_ibusy); sample int_monitor.$req_rel_hit_skew3_ibusy { state req_rel_hit_skew3_ibusy(0:1) if (int_monitor.$req_rel_hit_skew3_ibusy == 1); } } coverage_group req_rel_hit_skew4_ibusy_cov { sample_event = @(int_monitor.$req_rel_hit_skew4_ibusy); sample int_monitor.$req_rel_hit_skew4_ibusy { state req_rel_hit_skew4_ibusy(0:1) if (int_monitor.$req_rel_hit_skew4_ibusy == 1); } } coverage_group req_rel_hit_skew5_ibusy_cov { sample_event = @(int_monitor.$req_rel_hit_skew5_ibusy); sample int_monitor.$req_rel_hit_skew5_ibusy { state req_rel_hit_skew5_ibusy(0:1) if (int_monitor.$req_rel_hit_skew5_ibusy == 1); } } coverage_group rel_req_hit_skew1_noibusy_cov { sample_event = @(int_monitor.$rel_req_hit_skew1_noibusy ); sample int_monitor.$rel_req_hit_skew1_noibusy { state rel_req_hit_skew1_noibusy(0:1) if (int_monitor.$rel_req_hit_skew1_noibusy == 1); } } coverage_group rel_req_hit_skew2_noibusy_cov { sample_event = @(int_monitor.$rel_req_hit_skew2_noibusy ); sample int_monitor.$rel_req_hit_skew2_noibusy { state rel_req_hit_skew2_noibusy(0:1) if (int_monitor.$rel_req_hit_skew2_noibusy == 1); } } coverage_group rel_req_hit_skew3_noibusy_cov { sample_event = @(int_monitor.$rel_req_hit_skew3_noibusy ); sample int_monitor.$rel_req_hit_skew3_noibusy { state rel_req_hit_skew3_noibusy(0:1) if (int_monitor.$rel_req_hit_skew3_noibusy == 1); } } coverage_group rel_req_hit_skew4_noibusy_cov { sample_event = @(int_monitor.$rel_req_hit_skew4_noibusy ); sample int_monitor.$rel_req_hit_skew4_noibusy { state rel_req_hit_skew4_noibusy(0:1) if (int_monitor.$rel_req_hit_skew4_noibusy == 1); } } coverage_group rel_req_hit_skew5_noibusy_cov { sample_event = @(int_monitor.$rel_req_hit_skew5_noibusy ); sample int_monitor.$rel_req_hit_skew5_noibusy { state rel_req_hit_skew5_noibusy(0:1) if (int_monitor.$rel_req_hit_skew5_noibusy == 1); } } coverage_group rel_req_hit_skew1_ibusy_cov { sample_event = @(int_monitor.$rel_req_hit_skew1_ibusy ); sample int_monitor.$rel_req_hit_skew1_ibusy { state rel_req_hit_skew1_ibusy(0:1) if (int_monitor.$rel_req_hit_skew1_ibusy == 1); } } coverage_group rel_req_hit_skew2_ibusy_cov { sample_event = @(int_monitor.$rel_req_hit_skew2_ibusy ); sample int_monitor.$rel_req_hit_skew2_ibusy { state rel_req_hit_skew2_ibusy(0:1) if (int_monitor.$rel_req_hit_skew2_ibusy == 1); } } coverage_group rel_req_hit_skew3_ibusy_cov { sample_event = @(int_monitor.$rel_req_hit_skew3_ibusy ); sample int_monitor.$rel_req_hit_skew3_ibusy { state rel_req_hit_skew3_ibusy(0:1) if (int_monitor.$rel_req_hit_skew3_ibusy == 1); } } coverage_group rel_req_hit_skew4_ibusy_cov { sample_event = @(int_monitor.$rel_req_hit_skew4_ibusy ); sample int_monitor.$rel_req_hit_skew4_ibusy { state rel_req_hit_skew4_ibusy(0:1) if (int_monitor.$rel_req_hit_skew4_ibusy == 1); } } coverage_group rel_req_hit_skew5_ibusy_cov { sample_event = @(int_monitor.$rel_req_hit_skew5_ibusy ); sample int_monitor.$rel_req_hit_skew5_ibusy { state rel_req_hit_skew5_ibusy(0:1) if (int_monitor.$rel_req_hit_skew5_ibusy == 1); } } coverage_group int_mon_actv_asserts_during_ibusy_cov { sample_event = @(int_monitor.$ibusy); sample actv_asserts_during_ibusy { state actv_asserts_during_ibusy(0:1) if (actv_asserts_during_ibusy == 1); } } coverage_group int_mon_ibusy_hi_within_actv_cov { sample_event = @(int_monitor.$activate_ig_sm); sample ibusy_hi_within_actv { state ibusy_hi_within_actv(0:1) if (ibusy_hi_within_actv == 1); } } coverage_group group0_intr_rel_after_ibusy_cov { sample_event = wait_var(group0_intr_rel_after_ibusy); sample group0_intr_rel_after_ibusy { state group0_intr_rel_after_ibusy(0:1) if (group0_intr_rel_after_ibusy == 1); } } coverage_group group16_intr_rel_after_ibusy_cov { sample_event = wait_var(group16_intr_rel_after_ibusy); sample group16_intr_rel_after_ibusy { state group16_intr_rel_after_ibusy(0:1) if (group16_intr_rel_after_ibusy == 1); } } coverage_group group32_intr_rel_after_ibusy_cov { sample_event = wait_var(group32_intr_rel_after_ibusy); sample group32_intr_rel_after_ibusy { state group32_intr_rel_after_ibusy(0:1) if (group32_intr_rel_after_ibusy == 1); } } coverage_group group48_intr_rel_after_ibusy_cov { sample_event = wait_var(group48_intr_rel_after_ibusy); sample group48_intr_rel_after_ibusy { state group48_intr_rel_after_ibusy(0:1) if (group48_intr_rel_after_ibusy == 1); } } task new(); task monitor_sm_active_rel_overlap(); task monitor_sm_active_rel_overlap_during_ibusy(); task monitor_int_sm_active_during_ibusy(); task monitor_ibusy_during_int_sm_active(); task monitor_smrel_4grp_after_ibusy(); } task CNiuIntMonitor::new() { int_monitor = int_mon_port_bind; if(get_plus_arg(CHECK,"INT_MON_ON")) { INT_MON_ON = 1; req_rel_hit_skew0_noibusy_cov = new(); req_rel_hit_skew1_noibusy_cov = new(); req_rel_hit_skew2_noibusy_cov = new(); req_rel_hit_skew3_noibusy_cov = new(); req_rel_hit_skew4_noibusy_cov = new(); req_rel_hit_skew5_noibusy_cov = new(); req_rel_hit_skew0_ibusy_cov = new(); req_rel_hit_skew1_ibusy_cov = new(); req_rel_hit_skew2_ibusy_cov = new(); req_rel_hit_skew3_ibusy_cov = new(); req_rel_hit_skew4_ibusy_cov = new(); req_rel_hit_skew5_ibusy_cov = new(); rel_req_hit_skew1_noibusy_cov = new(); rel_req_hit_skew2_noibusy_cov = new(); rel_req_hit_skew3_noibusy_cov = new(); rel_req_hit_skew4_noibusy_cov = new(); rel_req_hit_skew5_noibusy_cov = new(); rel_req_hit_skew1_ibusy_cov = new(); rel_req_hit_skew2_ibusy_cov = new(); rel_req_hit_skew3_ibusy_cov = new(); rel_req_hit_skew4_ibusy_cov = new(); rel_req_hit_skew5_ibusy_cov = new(); int_mon_actv_asserts_during_ibusy_cov = new(); int_mon_ibusy_hi_within_actv_cov = new(); group0_intr_rel_after_ibusy_cov = new(); group16_intr_rel_after_ibusy_cov = new(); group32_intr_rel_after_ibusy_cov = new(); group48_intr_rel_after_ibusy_cov = new(); printf(" Intr_mon: INT Monitor coverage objects enabled... \n"); } fork monitor_sm_active_rel_overlap(); monitor_sm_active_rel_overlap_during_ibusy(); monitor_int_sm_active_during_ibusy(); monitor_ibusy_during_int_sm_active(); monitor_smrel_4grp_after_ibusy(); join none } /* Monitor if activate_ig_sm signal overlap with release signal */ task CNiuIntMonitor::monitor_sm_active_rel_overlap() { /* monitor state machine activate */ if(INT_MON_ON){ printf (" Monitoring activate_ig_sm...\n"); while(TRUE) { @ (int_monitor.$activate_ig_sm); if(int_monitor.$activate_ig_sm_rel) { int_active_rel_ovrlap = 1; printf (" Intr_mon: activate_ig_sm and activate_ig_sm_rel overlap occured...\n"); } else { int_active_rel_ovrlap = 0; } } } } /* Monitor if the overlap occurs when ibusy signal is high */ task CNiuIntMonitor::monitor_sm_active_rel_overlap_during_ibusy() { if(INT_MON_ON){ printf (" Monitoring if activate_ig_sm and rel occur during ibusy...\n"); while(TRUE) { @ (int_monitor.$ibusy); if(int_monitor.$activate_ig_sm && int_monitor.$activate_ig_sm_rel) { int_active_rel_ibusy_ovrlap = 1; printf (" Intr_mon: activate_ig_sm and activate_ig_sm_rel overlap with ibusy occured...\n"); } else { int_active_rel_ibusy_ovrlap = 0; } } } } /* Monitor if activate_ig_sm asserts while ibusy and deasserts after ibusy */ /* Test Case 13 */ task CNiuIntMonitor::monitor_int_sm_active_during_ibusy() { if(INT_MON_ON){ printf (" Monitoring activate_ig_sm during ibusy...\n"); while(TRUE) { @ (posedge int_monitor.$activate_ig_sm); if(int_monitor.$ibusy) { activate_ig_sm_during_ibusy = 1; } @ (negedge int_monitor.$ibusy); if(int_monitor.$activate_ig_sm && activate_ig_sm_during_ibusy ) { actv_asserts_during_ibusy = 1; printf (" Intr_mon: activate_ig_sm assert after ibusy, deasserts after ibusy...\n"); activate_ig_sm_during_ibusy = 0; } @ (negedge int_monitor.$activate_ig_sm); if (actv_asserts_during_ibusy) { actv_asserts_during_ibusy = 0; } } } } /* Monitor if ibusy gets asserted, then deasserted while activate_ig_sm is high */ /* Test Case 12 */ task CNiuIntMonitor::monitor_ibusy_during_int_sm_active() { /* monitor ibusy when state machine activate_ig is asserted */ if(INT_MON_ON){ printf (" Monitoring ibusy during activate_ig_sm...\n"); while(TRUE) { @ (posedge int_monitor.$ibusy); if(int_monitor.$activate_ig_sm) { ibusy_during_activate_ig_sm = 1; } @ (negedge int_monitor.$ibusy); if(int_monitor.$activate_ig_sm && ibusy_during_activate_ig_sm ) { ibusy_hi_within_actv = 1; printf (" Intr_mon: ibusy asserts and deasserts during activate_ig_sm...\n"); ibusy_during_activate_ig_sm = 0; } @ (negedge int_monitor.$activate_ig_sm); if(ibusy_hi_within_actv) { ibusy_hi_within_actv = 0; } } } } /* Monitor that sm_rel for groups 0, 16, 32, 48 is released when */ /* ibusy goes low... */ task CNiuIntMonitor::monitor_smrel_4grp_after_ibusy() { #define GROUP0 64'h0000000000000001 #define GROUP16 64'h0000000000010000 #define GROUP32 64'h0000000100000000 #define GROUP48 64'h0001000000000000 if(INT_MON_ON){ printf (" Monitoring sm_rel for int groups 0, 16, 32, 48...\n"); while(TRUE) { @ (posedge int_monitor.$activate_ig_sm_rel); /* intr_rel_group changes with activate_ig_sm_rel */ if(int_monitor.$ibusy) { ibusy_trigger = 1; } @ (negedge CLOCK); if(ibusy_trigger && ~latch_rel_info){ latch_rel_info = 1; case( int_monitor.$intr_rel_group ) { GROUP0: { intr_rel_group0 = 1; } GROUP16: { intr_rel_group16 = 1; } GROUP32: { intr_rel_group32 = 1; } GROUP48: { intr_rel_group48 = 1; } default: intr_rel_othergrp = 1; } } @ (negedge int_monitor.$ibusy); { ibusy_trigger = 0; latch_rel_info = 0; if(int_monitor.$activate_ig_sm_rel){ if(intr_rel_group0) { printf (" Intr_mon: group 0 intr_rel after ibusy\n"); /* this is where we count events... */ /* intr_rel_group0_count++; */ group0_intr_rel_after_ibusy = 1; } if(intr_rel_group16) { printf (" Intr_mon: group 16 intr_rel after ibusy\n"); /* intr_rel_group16_count++; */ group16_intr_rel_after_ibusy = 1; } if(intr_rel_group32) { printf (" Intr_mon: group 32 intr_rel after ibusy\n"); /* intr_rel_group32_count++; */ group32_intr_rel_after_ibusy = 1; } if(intr_rel_group48) { printf (" Intr_mon: group 48 intr_rel after ibusy\n"); /* intr_rel_group48_count++; */ group48_intr_rel_after_ibusy = 1; } } } @ (negedge int_monitor.$activate_ig_sm_rel); if(int_monitor.$ibusy && ibusy_trigger){ if(intr_rel_group0 || intr_rel_group16 || intr_rel_group32 || intr_rel_group48) { be_msg.print(e_mesg_error, "Intr_mon", "", "intr_rel deasserted during ibusy for groups 0, 16, 32, 48 at time %0d. Exiting the simulation \n", get_time(LO)); }else{ if(intr_rel_group0) { intr_rel_group0 = 0; group0_intr_rel_after_ibusy = 0; } if(intr_rel_group16) { intr_rel_group16 = 0; group16_intr_rel_after_ibusy = 0; } if(intr_rel_group32) { intr_rel_group32 = 0; group32_intr_rel_after_ibusy = 0; } if(intr_rel_group48) { intr_rel_group48 = 0; group48_intr_rel_after_ibusy = 0; } if(intr_rel_othergrp) { printf (" Intr_mon: intr_rel during ibusy for other groups\n"); intr_rel_othergrp = 0; /* intr_rel_othergrp_count++; */ } } } } // while } // if(INT_MON_ON) } // task #endif // if NIU_GATE... else...endif