HierarchyFilesModulesSignalsTasksFunctionsHelp

/******************************************************************************/ 
/*                                                                            */ 
/* Copyright (c) 1999 Sun Microsystems, Inc. All rights reserved.             */ 
/*                                                                            */ 
/* The contents of this file are subject to the current version of the Sun    */ 
/* Community Source License, microSPARCII ("the License"). You may not use    */ 
/* this file except in compliance with the License.  You may obtain a copy    */ 
/* of the License by searching for "Sun Community Source License" on the      */ 
/* World Wide Web at http://www.sun.com. See the License for the rights,      */ 
/* obligations, and limitations governing use of the contents of this file.   */ 
/*                                                                            */ 
/* Sun Microsystems, Inc. has intellectual property rights relating to the    */ 
/* technology embodied in these files. In particular, and without limitation, */ 
/* these intellectual property rights may include one or more U.S. patents,   */ 
/* foreign patents, or pending applications.                                  */ 
/*                                                                            */ 
/* Sun, Sun Microsystems, the Sun logo, all Sun-based trademarks and logos,   */ 
/* Solaris, Java and all Java-based trademarks and logos are trademarks or    */ 
/* registered trademarks of Sun Microsystems, Inc. in the United States and   */ 
/* other countries. microSPARC is a trademark or registered trademark of      */ 
/* SPARC International, Inc. All SPARC trademarks are used under license and  */ 
/* are trademarks or registered trademarks of SPARC International, Inc. in    */ 
/* the United States and other countries. Products bearing SPARC trademarks   */ 
/* are based upon an architecture developed by Sun Microsystems, Inc.         */ 
/*                                                                            */ 
/******************************************************************************/ 

    `define C `CYCLETIME
    `define hC (`C/2)
    `define Cstop (`C-3)

module Mclocks (
	clock
      ) ;


	output clock ;
	reg clock ;
	integer phase ; // Current phase of clock (between 0 and `C-1)

	reg STOP;        // flag used to indicate the end of an
			// interactive task
	
	reg RST_TMO;    // flag used to reset the timeout checkers

	/*wire*/ reg RESET_IN ; // This is forced during simulation to initiate reset
				// Changed wire to reg for Chronologic
	
	reg [31:0] cycle_count;	// cycle counter

	// 'Slave' copy of cycle_count, delayed by #1 so it can be sampled at
	//     the rising edge of clock.
	reg [31:0]  cycle_count_s ;
	initial cycle_count_s = 0 ;
	always @cycle_count #1 cycle_count_s = cycle_count ;

	// value of cycle_count at which mux select compares will begin
	reg [31:0] compare_threshold ;
	initial compare_threshold = 9999999 ;

	// trigger used by mux select compare code
	event compare_trigger ;

	// trigger the mux select compare logic for every cycle after
	// cycle_count has exceeded compare_threshold
	always @(posedge clock) begin
	    if (cycle_count > compare_threshold) begin
		#(`CYCLETIME - 3) -> compare_trigger ;
	    end
	end

	reg reset_clears_count ; // When set, RESET will clear cycle_count

	reg [31:0] sample_count; // Counter for dcc samples

	reg end_run;             // Flag set when diagnostic finishes
	reg end_run_error ;      // Flag set when diag signals failure
	reg ignore_end_run ;	 // When set, ignore end_run
	initial ignore_end_run = 0 ;

	reg scan_operation ;	// Flag set when doing a scan/debug operation
	initial scan_operation = 0 ;

	reg [31:0] trace_mcd ;	// File descriptor used for trace file

	reg [31:0] breakpoint ;  // 32 independent breakpoint flags

	// Mask of breakpoints for which clocking should continue after the
	//     breakpoint hits - used by vsh @bp.
	reg [31:0] bp_continue ;

	// Breakpoint test values from previous cycle
	reg [63:0] lastbreak [0:31] ;  // Can compare up to 64 bits
	reg dsbl_breakpoints ;   // Useful during reset sequences
	event breaktest ;        // Breakpoints are evaluated @breaktest
	event samplesig ;        // dcc samples are taken @samplesig
	event vecsig ;           // vector samples are taken @vecsig
	event piggy_isig ;       // Apply piggyback inputs
	event piggy_osig ;       // Test piggyback outputs
	event piggy_mcsig ;      // Test piggyback clock outputs at midcycle

   // This register is a counter for error messages.  It should be incremented
   //    by any code which prints a '***' message.  It is useful as an object
   //    to be tested by a vfront breakpoint.
       reg [31:0] error_count ; initial error_count = 0 ;

   // Another one for warning messages.
       reg [31:0] warning_count ; initial warning_count = 0 ;

	event bpdisp ;           // Display a breakpoint
	reg [31:0] bpdispnum ;   // Which loop to trigger for display

	event killtest ;         // Kills a loop
	reg [31:0] killnum ;     // Which one to kill

	reg enbl_icon ; initial enbl_icon=0 ;
	reg [2047:0] icon_dir ;

	// In vsh mode, append <del><nl> to end of $write strings.
	reg [15:0] vsh_nl ; initial vsh_nl = 0 ;

	// String which holds the name of the working directory for the
	//     current simulation run.  Use when opening files.
	reg [2047:0] working_dir ;   // Big enough for 256 chars.

	// Activate this event whenever we change working_dir;
	//     code may use this as a signal to close old files and
	//     open new ones.
	event new_working_dir ;

	initial begin
		clock = 0;
		phase = `Cstop ;
		STOP = 0;
		RST_TMO = 0;
		cycle_count = 0;
		sample_count = 0;
		reset_clears_count = 0 ;
		breakpoint = 0;
		bp_continue = 0;
		dsbl_breakpoints = 0;
		working_dir = "." ;

		stop;	// enable the stop task
	end


	// task to stop simulation whenever STOP is wiggled

	task stop;
		forever @STOP begin
		    $stop(0);
		    // Flush the VCD buffer
		    $dumpflush ;
		end
	endtask


	// Task to execute, with no clocks

	task sim;
	   input [31:0] n;
	   begin
	     RST_TMO = ~RST_TMO ;
	     #n STOP = ~STOP;
	    end
	endtask

	// This prevents simulation from 'running off the end'
	//    and terminating verilog
	// If RST_TMO is not toggled within 1000 time units,
	//    this code triggers a $stop.
	always @(posedge RST_TMO) begin :timeout1
	    disable timeout0 ;
	    #(2*`C)
	    $display("Timeout");
	    STOP = ~STOP ;
	    #0 RST_TMO = ~RST_TMO ;
	end
	always @(negedge RST_TMO) begin :timeout0
	    disable timeout1 ;
	    #(2*`C)
	    $display("Timeout");
	    STOP = ~STOP ;
	    #0 RST_TMO = ~RST_TMO ;
	end


	task toggle_clock ;
	   begin
	      clock = ~clock ;

	      // Zero the cycle count on startup reset, but not 
	      //    error reset
	      if (clock) begin
		 phase = 0 ;
		 if (reset_clears_count && RESET_IN) begin
		    cycle_count = 0 ;
		    sample_count = 0 ;
		 end
		 else cycle_count = cycle_count + 1;
	      end
	      else phase = `hC ;
	   end
	endtask

	// Piggyback inputs are applied at #2 into the cycle (since all
	//     FFs have #1 Clk->Q and all gates have #0 delay).
	// Piggyback clock outputs are tested at #1 before the next negedge
	//     clock.
	// Piggyback outputs are tested at #1 before the next posedge clock;
	//     vector capture happens at the same time.
	always @(posedge clock) fork
	    #2 -> piggy_isig ;
	    #((`C>>1)-1) -> piggy_mcsig ;
	    #(`C-1) begin
		-> piggy_osig ;
		-> vecsig ;
	    end
	join

	// The above code doesn't get kicked for the very first cycle -
	//    apply the inputs at #1 after initial, and test the outputs at
	//    #1 before the first posedge clock.
	initial fork
	    #1 -> piggy_isig ;
	    #(`C-`Cstop-1) begin
		-> piggy_osig ;
		-> vecsig ;
	    end
	join

	// Note: piggy_isig is also activated at the start of the 'cycles'
	//       task.

	task change_icon ;
	   input [1023:0] icon ;
	   $write("]I%0s/%0s\\%0s", icon_dir, icon, vsh_nl) ;
	endtask

	// Task to issue clocks, stopping at a breakpoint
	//	or end of diagnostic.
	task cycles ;
	   input [31:0] n;      // Iteration count
	   input [31:0] nticks; // Time units per iteration
	   input [31:0] nzeros; // Number of zero-delay samples per iteration
	   input [31:0] disp_each_iter;
	   input fastmode ;	// dummy for scan debugger - see clocks_scan.v

	   integer nextedge ;
	   reg [7:0] ch ;

	   begin
		// Disable stop task so that displays won't stop simulation
		if(disp_each_iter==1) disable stop;

		end_run = 0;	// clear flags which stops simulation
		end_run_error = 0 ;
		breakpoint = 0 ;

		// Update the dcc samples and piggyback inputs to reflect any
		//     changes that were made interactively.
		#0 ->samplesig ; ->piggy_isig ;

		// Change icon for this window
		if (enbl_icon) change_icon("vfront.icon") ;

		while (
		    (n>0) && (((end_run & ~ignore_end_run) | breakpoint)==0)
		) begin
		   n=n-1;

		   RST_TMO = ~RST_TMO ;

		   // Compute time to next clock edge
		   // This expression always gives a number between 1 and `hC.
		   nextedge = `hC-(phase%`hC) ;

		// Simulate for the required amount of time
		   // Two clock transitions:
		   if (nticks>=(nextedge+`hC)) begin
		      #nextedge toggle_clock ;
		      #`hC toggle_clock ;
		      #(nticks-nextedge-`hC) ;
		      phase = phase + (nticks-nextedge-`hC) ;
		   end
		   // One clock transition:
		   else if (nticks>=nextedge) begin
		      #nextedge toggle_clock ;
		      #(nticks-nextedge) ;
		      phase = phase + (nticks-nextedge) ;
		   end
		   // No clock transitions:
		   // Don't do a #0 if nticks==0 - we do one below.
		   else if (nticks > 0) begin
		      #nticks ;
		      phase = phase + nticks ;
		   end

		   repeat (nzeros) begin


		      // Now display something, if specified
		      case (disp_each_iter)
			     // The 2 is vestigial from Sunup
			     2: begin
				ch = 
				   ((cycle_count%10)==0)
				      ? ("0"+((cycle_count/10)%10)) : (
				   (phase==`Cstop) ? "." : (
				   ",") ) ;
				// If a multiple of 100, print the whole
				//     cycle count at beginning of line.
				if (ch=="0")
				    $write("\n%0d%0s", cycle_count, vsh_nl) ;
				else
				    $write("%c%0s", ch, vsh_nl) ;
			     end
		      endcase

		      // Do a dcc sample
		      sample_count = sample_count + 1 ;
		      #0     // Wait for Mccdisp.cidx to be updated
		      ->samplesig ;

		      #0 ;
		   end

		   // Trigger breakpoint test event
		   if (!dsbl_breakpoints) ->breaktest ;
		   #0 ;  // Wait for breakpoints to be set before loop test

		end

		// Trigger piggyback output test, so we'll see this cycle's
		//     mismatches before the prompt (we'll see them again
		//     if we resume simulation).
		-> piggy_osig ;

	     // Done with loop - print messages.

		if (disp_each_iter==2) $display("");

		// Print explanatory messages

		// If we hit only @bp breakpoints in vsh, print a line
		//     which will cause vsh to do the remaining clocks.
		if ((breakpoint&bp_continue) && !(breakpoint&~bp_continue))
		    $display("\033@@Mclocks.cycles(%0d,%0d,%0d,%0d,%0d);.",
			n,nticks,nzeros,disp_each_iter,fastmode) ;

		else begin
		    if (breakpoint!=0) $write("Breakpoint: ") ;
		    if (end_run & ~ignore_end_run) begin
			if (end_run_error)
			    $write("******Diagnostic failed: ") ;
			else
			    $write("Diagnostic completed: ") ;
		//        $sas_verbose(1);
			if (sastasks.SAS == 1)
			    if ($sas_command("quit"))
        	                $display("Could not quit mpsas on stop.");
		    end
             	end


		$write("Clocks stopped at cycle %0d",cycle_count) ;

		if ((nticks!=`C) || (phase!=`Cstop) )
		   $write(" (phase=%0d/%0d)", phase, `C) ;
		if (cycle_count != sample_count)
		   $write(", sample %0d", sample_count) ;
		$display("") ;

		if (enbl_icon)
		   change_icon(
		       (end_run & ~ignore_end_run)
			   ? "vfront_done.icon"
			   : (breakpoint ? "vfront_break.icon"
					 : "vfront_stop.icon")
		   ) ;

		#0 ;

		if(disp_each_iter==1)	// re-enable stop task
					// and trigger it in parallel
		fork
		   stop;
		   STOP = ~STOP;
		join
		else STOP = ~STOP;		// trigger stop

	   end
	endtask

	// Task to display a breakpoint
	task dispbp ;
	   input [31:0] n ;
	   begin
	      // Trigger display loop (n+100)
	      bpdispnum = n+100 ;
	      ->bpdisp;
	      // Wait for it to finish
	      #0 ;
	   end
	endtask


   // Convert number to 10-digit verilog string (decimal representation).
   // Suppress leading zeros.
   function [79:0] dec_str ;
      input [31:0] n ;
      if (^n===1'bx) dec_str = "xxxxxxxxxx" ;
      else if (n==0) dec_str = "0" << 72 ;
      else begin
	 dec_str = 0 ;   // Initialize to all nulls
	 while (n != 0) begin
	   dec_str = (dec_str >> 8) | (("0"+(n%10)) << 72) ;
	   n = n/10 ;
	 end
      end
   endfunction

   reg saved ; initial saved = 0 ;
   task save ;
      begin
	 $display("Saving simulation state at cycle %0d in file save_%0d . . .", cycle_count, sample_count) ;

	 // Copy the trace.v file
	 if (trace_mcd==0) begin
	    $system({"echo 'no trace file' > ",
			Mclocks.working_dir,
			"/save_", dec_str(sample_count), ".trace"}) ;
	 end
	 else begin
	    $system({"cp ", Mclocks.working_dir, "/trace.v ",
			Mclocks.working_dir,
			"/save_", dec_str(sample_count), ".trace"}) ;
	 end

	 // Copy the dcc.log file

	 // Make one if it doesn't exist
	 $system({"cat /dev/null>>", Mclocks.working_dir,"/dcc.log"});
	 $system({"cp ",Mclocks.working_dir,"/dcc.log ",
		     Mclocks.working_dir,
		     "/save_", dec_str(sample_count), ".dcc"}) ;

	 // Now do the $save
	 if (saved)
	    $incsave({Mclocks.working_dir,"/save_", dec_str(sample_count)}) ;
	 else $save({Mclocks.working_dir,"/save_", dec_str(sample_count)}) ;

	 /*----- Simulation will resume here after a $restart ------*/

	 saved = 1 ;
	 $display("Continuing simulation at cycle %0d", cycle_count) ;
      end
   endtask

    // Task to change working_dir and signal the change.
    // If new_log is true, close the verilog.log file and open a new one
    //    in the new directory.
    task chdir ;
	input [2047:0] new_dir ;
	input [2047:0] new_log ;
	begin
	    if (new_log) begin
		$display("Opening new log file %0s/%0s", new_dir, new_log) ;
		$log({new_dir, "/", new_log}) ;
	    end
	    $display("Previous working_dir was %0s", working_dir) ;
	    working_dir = new_dir ;
	    // Set up a symbolic link within the directory we were 
	    //     started up in (the link is used by I-I sas).
	    $system({"rm -f working_dir; ln -s ",
			working_dir, " working_dir"}) ;
	    $display("New working_dir is %0s", working_dir) ;
	    -> new_working_dir ;
	end
    endtask

    // Print a value as exactly n binary digits
    task print_bits ;
	input [31:0] n ;
	input [63:0] x ;
	integer i ;
	for (i=n-1 ; i>=0 ; i=i-1) $write("%b", x[i]) ;
    endtask

    task print_error ;
	input [2047:0] string ;
	begin
	    $display("\n*** %0d: %0s", cycle_count_s, string) ;
	    error_count = error_count + 1 ;
	end
    endtask

endmodule
HierarchyFilesModulesSignalsTasksFunctionsHelp

This page: Created:Thu Aug 19 11:57:52 1999
From: ../../../sparc_v8/system/rtl/clocks.v

Verilog converted to html by v2html 5.0 (written by Costas Calamvokis).Help