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.         */ 
/*                                                                            */ 
/******************************************************************************/ 
/***************************************************************************
****************************************************************************
***
***  Program File:  @(#)misc_tasks.v
***
****************************************************************************
****************************************************************************/

// Code for testing clock and scan logic
module misc_tasks ;

    // Use this in calls to the tap_op tasks
    reg [31:0] tdo_bits ;

    // Reset JTAG, clk_cntl, and internal logic
    task jtag_clk_rst ;
	input lofreq_clk_rst ;
	fork

	    // Run clocks forever - we'll turn them off below.
	    Mclocks.cycles('h7fffffff,20,1,2,0) ;

	    begin

		do_jtag_clk_rst(lofreq_clk_rst) ;

		// The next ext_clk will be gated through.  input_reset_l is
		//     still asserted.  Turn off Mclocks.clock .
		Mclocks.cycles.n = 0 ;

	    end

	join
    endtask

    // This does all the work, but doesn't $stop.  It can be invoked from
    //     other tasks.
    task do_jtag_clk_rst ;
	input lofreq_clk_rst ;
	begin

	    `BOARD.input_reset_l = 0 ;
	    `BOARD.jtag_trst_l = 0 ;

	    // Wait for jtag state machine to reset, then de-assert trst
	    @(posedge `BOARD.jtag_ck) ;
	    @(posedge `BOARD.jtag_ck) ;
	    #1 `BOARD.jtag_trst_l = 1 ;

	    fork

		// shift in '11' into the MSBs of the JTAG instruction
		//     register, so that it contains '110000', the
		//     clk_rst opcode.  Then continue on to
		//     Test-Logic-Reset.  clk_cntl will reset several times
		//     during this; the last reset is the input_clock posedge
		//     which comes just before the negedge of jtag_ck in the
		//     Update-DR cycle.  clk_rst_l will be asserted for
		//     four jtag_ck cycles.
		do_tap_op(4'hf, 4'hf, 11, 11'b11111000110, 11'b11111111111,
			11'b11111111111, 11'bx, tdo_bits) ;

		// If we want this to work at 'high speed', we have to disable
		//     the ext_clk input around transitions of the clk_rst_l
		//     signal, because the timing of this signal has not
		//     been analyzed.  Wait for clk_rst to be asserted,
		//     wait a couple of clock cycles, then enable ext_clk
		//     for one clock cycle (this give2 two ext_clk1
		//     pulses, since ext_clk1 is twice the frequency of
		//     Mclocks.clock).
		if (~lofreq_clk_rst) begin
		    @(posedge Mclocks.clock) #1 `BOARD.dsbl_ext_clk = 1 ;
		    @(negedge `rl_clk_cntl.clk_rst_l) ;
		    @(posedge Mclocks.clock) #1 ;
		    @(posedge Mclocks.clock) #1 ;
		    @(posedge Mclocks.clock) #1 `BOARD.dsbl_ext_clk = 0 ;
		    @(posedge Mclocks.clock) #1 `BOARD.dsbl_ext_clk = 1 ;
		end

	    join

	    // Clock controller has been reset - we're in the second half of
	    //     the first phase.  Turn clocks on if we turned them off.
	    if (~lofreq_clk_rst) begin
		@(posedge `BOARD.jtag_ck) #1 ;  // Sync up with jtag_ck

		// Start ext_clk so that the first 0->1 on free_clk
		//     coincides with a 0->1 on Mclocks.clock .
		@(negedge Mclocks.clock) #1 `BOARD.dsbl_ext_clk = 0 ;
	    end
 
            // The next ext_clk will be gated through.  input_reset_l is
            //     still asserted.

	end
    endtask

`ifdef CLK_MISC_GATE_LEVEL
    // .Lv names - .sv has escaped-ID instance names
    wire [3:0] jtag_state = ~{
	`rl_jtag_cntl.tapsm_fsm_Mflipflop_ar_3_3_dff.Q,
	`rl_jtag_cntl.tapsm_fsm_Mflipflop_ar_3_2_dff.Q,
	`rl_jtag_cntl.tapsm_fsm_Mflipflop_ar_3_1_dff.Q,
	`rl_jtag_cntl.tapsm_fsm_Mflipflop_ar_3_0_dff.Q
    } ;
`else
    wire [3:0] jtag_state = `rl_jtag_cntl.tapsm.tapc_state ;
`endif
    // These keep the same names in .Lv .  Escaped IDs in .sv, though . . .
    wire [5:0] jtag_instr = `rl_jtag_cntl.inst ;
    wire [2:0] free_phase = `rl_clk_cntl.free_phase ;

    // When set, print a comment on every jtag state change
    reg jtag_state_comments ; initial jtag_state_comments = 0 ;
    always @(jtag_state) if (jtag_state_comments)
	$fdisplay(Mccdisp.allvec_tto_mcd,
	    "---------- %0d: jtag_state<-%h, instr=%b ----------",
	    Mclocks.cycle_count_s, jtag_state, jtag_instr) ;

    task tap_op ;
	input [3:0] from_state ;
	input [3:0] to_state ;
	input [31:0] n ;
	input [31:0] tms_bits ;
	input [31:0] tdi_bits ;
	input [31:0] td_mask ;  // for each '1', scan in the corresponding bit
	input [31:0] scanout ;
	output [31:0] tdo_bits ;
	fork
	    // Run clocks forever - we'll turn them off below.
	    Mclocks.cycles('h7fffffff,20,1,2,0) ;

	    // While the clock generator is running, run the jtag state
	    //     machine.  Turn off clocks when we're done.
	    begin

		// Do the tap sequence
		do_tap_op(from_state, to_state, n, tms_bits, tdi_bits,
			    td_mask, scanout, tdo_bits) ;

		// Now turn off clocks - since jtag_ck period is at least
		//     twice the cycletime, clocks are guaranteed to
		//     stop before the next jtag_ck posedge.
		Mclocks.cycles.n = 0 ;

	    end

	join
    endtask

    // Issue up to 32 clocks worth of TAP operation
    task do_tap_op ;
	input [3:0] from_state ;
	input [3:0] to_state ;
	input [31:0] n ;
	input [31:0] tms_bits ;
	input [31:0] tdi_bits ;
	input [31:0] td_mask ;  // for each '1', scan in the corresponding bit
	input [31:0] scanout ;
	output [31:0] tdo_bits ;
	reg [31:0] tdo_bits ;
	integer i ;

	if (n>32) Mclocks.print_error("Too many bits to shift") ;
	else begin

	    $fdisplay(Mccdisp.allvec_tto_mcd,
		"---------- %0d: %0d-bit tap_op %h->%h ----------",
		Mclocks.cycle_count_s, n, from_state, to_state);

	    if (((^from_state)!==1'bx) && (jtag_state!==from_state)) begin
		$display("\n*** %0d: Expected jtag state %b, found %b, at start of %0d-bit tap_op", Mclocks.cycle_count_s, from_state, jtag_state, n) ;
		Mclocks.error_count = Mclocks.error_count + 1 ;
	    end

	    tdo_bits = 0 ;
	    for (i=0 ; i<n ; i=i+1) begin

		// Allow changes to propagate to jtag_tdo (it's on a
		//     negative-edge-triggered FF).
		if (`BOARD.jtag_ck) @(negedge `BOARD.jtag_ck) #2 ;

		`BOARD.jtag_ms = tms_bits[i] ;
		`BOARD.jtag_tdi =
		    td_mask[i] ? tdi_bits[i] : `BOARD.jtag_tdo ;

		@(posedge `BOARD.jtag_ck) begin
		    tdo_bits[i] = `BOARD.jtag_tdo ;
		end
		#2 ;
	    end

	    // We are now #2 after the last posedge jtag_ck, so
	    //     all state machine outputs have reached their
	    //     ending states.
	    // Check for proper ending state
	    if (((^to_state)!==1'bx) && (jtag_state!==to_state)) begin
		$display("\n*** %0d: Expected jtag state %b, found %b, at end of %0d-bit tap_op", Mclocks.cycle_count_s, to_state, jtag_state, n) ;
		Mclocks.error_count = Mclocks.error_count + 1 ;
	    end

	    // Check for expected scanout value - all this XORing is to
	    //     ignore match on 'x' bits in the scanout parameter.
	    scanout = scanout & ((1<<n)-1) ;  // Clear unused MSBs
	    if ( (tdo_bits^(scanout^scanout))!==scanout) begin
		$write("\n**** ") ;
		Mclocks.print_bits(n, tdo_bits) ;
		$write(" scanned out (cycle %0d)\n *** ",
		    Mclocks.cycle_count_s) ;
		Mclocks.print_bits(n, scanout) ;
		$display(" expected\n") ;
		Mclocks.error_count = Mclocks.error_count + 1 ;
	    end

	end
    endtask


    // Jtag clock

reg	[31:0]	tck_hi, tck_lo ;
reg	[31:0]	tck_period ;

// Use the $GetEnv pli option to pass the variable for tck_period

initial begin

	$GetEnv("tck_period", tck_period);
	tck_hi = (tck_period>>1);
	tck_lo = (tck_period-(tck_period>>1)) ;
end


    initial begin
	`BOARD.jtag_ck = 0 ;

	// Sync up with free clocks at startup .  This is useful only when
	//     the jtag_ck period is a multiple of the Mclocks.clock period.
	#(`TCK_START) `BOARD.jtag_ck = 1 ;

	forever begin
	    #(tck_hi) `BOARD.jtag_ck = 0 ;
	    #(tck_lo) `BOARD.jtag_ck = 1 ;
	end
    end

    task tap_clk ;
	input [31:0] n ;
	fork
	    // Clock forever (we'll terminate the loop when we've seen
	    //     enough tclk's.
	    Mclocks.cycles('h7fffffff,20,1,2,0) ;
	    begin
		// Count down tclk pulses, then terminate the clock loop
		repeat(n) @(posedge `BOARD.jtag_ck) ;
		Mclocks.cycles.n = 0 ;
	    end
	join
    endtask

    // Print a character after the Mclocks.cycle '.' to indicate special cycles
    wire #1 ref_clk_dly = `rl_clk_cntl.ss_clock_unbuf ;
    wire #1 free_clk_dly = `rl_clk_cntl.free_clock ;
    reg [7:0] clk_type, last_clk_type ; initial clk_type = 0 ;
    always @(posedge Mclocks.clock)

    // Print nothing in first half of free cycle
    if (free_clk_dly) last_clk_type = " " ;
    else begin

	clk_type = 

	    // Unknown state
	    ((`rl_clk_cntl.stopped
		^ ref_clk_dly
		^ free_clk_dly
		^`rl_jtag_cntl.sys_sen
		^`misc.reset_nonwd)===1'bx)		? "X" : (

	    // Clocks stopped
	    (ref_clk_dly & `rl_clk_cntl.stopped)	? "_" : (

	    // Clock pause (rcc_clk but no ss_clock)
	    (ref_clk_dly & ~`rl_clk_cntl.stopped)	? "p" : (

	    // Scan shift
	    `rl_jtag_cntl.sys_sen			? "s" : (

	    // Reset
	    `misc.reset_nonwd				? "r" : (

	    0 ))))) ;

	// Mclocks.cycle has already printed the '.', etc, for the cycle
	//     which ends at this posedge; now print the character (if any)
	//     which describes the cycle we just finished.  Also, if this was
	//     the first normal cycle after some abnormal ones, print a '+'
	//     (this makes it easier to see a single-step, for example).
	if (clk_type) $write("%c%0s", clk_type, Mclocks.vsh_nl) ;
	else if (last_clk_type)	$write("+%0s", Mclocks.vsh_nl) ;

	// For next time . . .
	last_clk_type = clk_type ;

    end

    // Serial data shift to or from the given buffer
    // On entry, you must be Exit1-DR state
    // On exit, we are in Run-Test-Idle state
`ifdef VCS
`else
    task data_shift ;
    input [31:0] n ;		// Total number of bits to scan
    input [31:0] pause_interval ;	// Number of bits to scan between pauses
    input write ;		// 1->write_chain, 0->read_chain
    inout [8191:0] buffer ;

    reg [31:0] scanin_bits, scanin_mask, maxbits ;
    reg [8191:0] scanout_bits ;
    reg [4:0] dummy5 ;
    integer lsb, next_lsb, this_n ;
    fork

	// Run clocks forever - we'll turn them off below
	Mclocks.cycles('h7fffffff,20,1,2,0) ;

	// While clocks are running, do the scan shift.  Turn off clocks
	//     when we're done.
	begin

	    // If no pause is specified, shift 32 bits at a time
	    maxbits = pause_interval ? pause_interval : 32 ;

	    if (write) begin
		// Scan in every bit
		scanin_mask = -1 ;
	    end
	    else begin
		// Recirculate the scanout data for read_chain
		scanin_mask = 0 ;
		scanin_bits = 'bx ;

		buffer = 0 ;
	    end

	    if (pause_interval==0) begin
		// No pause - transition to Shift-DR before entering the loop.
		do_tap_op(4'h1, 4'h2, 5, 5'b01000, 5'bx, 5'bx, 5'bx, dummy5) ;
	    end

	    lsb = 0 ;
	    while (lsb<n) begin
		next_lsb = lsb + maxbits ;
		if (next_lsb>n) next_lsb = n ;
		this_n = next_lsb - lsb ;
		$display("---- %0d: shifting bits %0d:%0d ----",
		    Mclocks.cycle_count_s, (next_lsb-1), lsb) ;

		if (write) scanin_bits = buffer >> lsb ;

		if (pause_interval) begin

		    // Go to Shift-DR (5 clocks), then do the data shift (this_n
		    //     clocks), ending up in Exit1-DR.
		    do_tap_op(4'h1, 4'h1,
			(this_n+5),
			{(1<<(this_n-1)), 5'b01000},
			{scanin_bits,5'bx}, {scanin_mask,5'bx},
			32'bx, {scanout_bits,dummy5}) ;
		end

		else begin

		    // No pause - just do the data shift.
		    // Stay in Shift-DR unless this is the last shift - then
		    //     go to Exit1-DR.
		    do_tap_op(4'h2, ((next_lsb==n) ? 4'h1 : 4'h2),
			this_n,
			((next_lsb==n) ? (1<<(this_n-1)) : 0),
			scanin_bits, scanin_mask,
			32'bx, scanout_bits) ;
		end

		if (~write) buffer = buffer | (scanout_bits<<lsb) ;

		lsb = next_lsb ;
	    end

	    // In case we monitor these in a vcd file, signal that we're done
	    //     with the data shift.
	    lsb = 'bx ;
	    next_lsb = 'bx ;

	    // Stop in Run-Test-Idle
	    do_tap_op(4'h1, 4'hc, 8, 8'b00011000,
				    'bx, 'bx, 'bx, scanout_bits) ;

	    // Turn off vsh clock generator
	    Mclocks.cycles.n = 0 ;

	end

    join
    endtask
`endif
endmodule
HierarchyFilesModulesSignalsTasksFunctionsHelp

This page: Created:Thu Aug 19 12:02:12 1999
From: ../../../sparc_v8/env/rtl/misc_tasks.v

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