HierarchyFilesModulesSignalsTasksFunctionsHelp
12

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

/* Changes:
   6/22/98: changed pcr[31:0] assignment when in MMU_GATE_LEVEL,
		     according to Seagle synthesis netlist.

*/
  

`ifdef VCS
`define NOFORCE 1
`endif

`ifdef GATELEVEL
`define NOFORCE 1
`endif

module Mtask ;


    // This should mirror the reset state machine - we're interested in
    //     knowing when rsm has been cleared by rcc_rst_l .
    Mflipflop_rh rst_rst(rst_initialized_l, 1'b1,
		~`misc.last_phi, ~(~`misc.rcc_rst_l & `misc.last_phi),
		`misc.rcc_clk) ;

    // When set, we'll use the CLK_RST TAP op to intialize clk_cntl; otherwise
    //     we'll just force clk_rst_l.  pll_byp_l must be 0 if this is set!
    reg use_jtag_clk_rst, lofreq_clk_rst ;
// add pci_slave_mode for 2.0 slave mode to enable a pci reset since
// Eagle won't be doing it.
    reg ext_clk2, pll_byp_l;
    initial begin
	$GetEnv("use_jtag_clk_rst", use_jtag_clk_rst) ;
	$GetEnv("lofreq_clk_rst", lofreq_clk_rst) ;
	$GetEnv("ext_clk2", ext_clk2) ;
	$GetEnv("pll_byp_l", pll_byp_l) ;
    end

    // Used by the mode scripts.  On exit, we are stopped just before the
    //     first non-reset ss_clock positive edge.
    task do_reset ;

	// 1-> initialize some IU signals for sas compatibility
	input init_iu ;

	begin

	    // Initialize some regs in the IU, for the sake of sas compare
	    if (init_iu) begin
`ifdef NOFORCE
		Mclocks.print_error("Must use a no-force mode with this model") ;
`else
		// force the tbr to agree with mpsas
		force `IU.iuchip.exec.tbr_mod.hld_tt = 0 ;
		force `IU.iuchip.exec.tbr_mod.tbr_unwr_wire = 'haa ;

		// force the WIM to agree with mpsas
		force `IU.iuchip.exec.wim_mod.wimm = 'hx ;

		// force the Y-reg to agree with mpsas
		force `IU.iuchip.exec.y_mod.ym = 'hx ;

		//	These are the undefined bits in the psr.  In order to
		//	make I-I compare with mpsas work, we initialize them
		//	to '0' here.
		force `IU.iuchip.exec.psr_mod.cc_mod.cc_next = 0 ;
		force complete.cc_w_out = 0 ;
		force `IU.iuchip.exec.psr_mod.cwp_mod.ncwp = 0 ;
		force complete.ncwp = 0 ;
		force `IU.iuchip.exec.psr_mod.pil_master_mux_out = 0 ;
		force `IU.iuchip.exec.psr_mod.result[12] = 0 ;
		force `IU.iuchip.exec.psr_mod.result[13] = 0 ;
		force `IU.iuchip.exec.psr_mod.hld_pilefec = 0 ;
		force `IU.iuchip.exec.psr_mod.ps_mod.nps = 1 ;
		force `SSPARC_CORE.pipe_hold4ic = 0 ;
`endif
	    end

	    // Do the reset
	    Msystem.input_reset_l = 0 ;
	    Msystem.jtag_trst_l = 0 ;
	    // for 2.0 slave mode turn on pci reset since eagle won't
            if (ext_clk2 && pll_byp_l)
		force Msystem.RSTnn = 0;

	    fork

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

		// Reset the clock controller
		#1 if (use_jtag_clk_rst) begin


		    // Can't do this if we're using the PLL
		    if (Msystem.pll_byp_l) Mclocks.print_error(
			"can't do JTAG CLK_RST when using the PLL") ;

		    // We're bypassing the PLL - use the CLK_RST JTAG op;
		    misc_tasks.do_jtag_clk_rst(lofreq_clk_rst) ;

		    // The clock controller has been reset, and we're ready
		    //     for the first ext_clk pulse.
		end
		else begin

		    // Just force clk_rst_l for one or two input_clock
		    //   posedges, to sync free_clk with Mclocks.clock.
		    force `rl_clk_cntl.clk_rst_l = 0 ;

		   // also force the path to pci clocks to initialize since
		   // the clk_rst_l has been removed from these flops -
		    force `rl_clk_cntl.free_phase_pci = 3'h0;

// the following three forces will be required for gate level, so just 
// leave them commented out for now. (replaces above 3)
//                    force `rl_clk_cntl.lsitkn_fppci_rega47Mflipflop_rh_2_0a47dffa47w0 = 0;
//                    force `rl_clk_cntl.lsitkn_fppci_rega47Mflipflop_rh_2_1a47dffa47w0 = 0;
//                    force `rl_clk_cntl.lsitkn_fppci_rega47Mflipflop_rh_2_2a47dffa47w0 = 0;

		    force `rl_clk_cntl.last_free_phase_pci = 0;
                    force `rl_clk_cntl.free_clock = 0;
		    force `rl_clk_cntl.pci_refclk_unbuf_ndly = 0;
		    force `rl_clk_cntl.pci_refclk_unbuf = 0;
		    force `rl_clk_cntl.pci_refclk_unbuf_ = 0;

		    // free_clk is being forced to 0 on each input_clock
		    //     posedge.  Wait for the input_clock at which
		    //     Mclocks.clock will toggle to 0.
		    @(negedge `rl_clk_cntl.input_clock)
		    if (~Mclocks.clock) @(posedge `rl_clk_cntl.input_clock) ;

		    // Release the reset
		    #1 release `rl_clk_cntl.clk_rst_l ;

		    // now release all the path to the pci clocks - 
		    release `rl_clk_cntl.free_phase_pci ;

// the following three releases will be required for gate level, so just 
// leave them commented out for now. (replaces above )
//                    release `rl_clk_cntl.lsitkn_fppci_rega47Mflipflop_rh_2_0a47dffa47w0 ;
//                    release `rl_clk_cntl.lsitkn_fppci_rega47Mflipflop_rh_2_1a47dffa47w0 ;
//                    release `rl_clk_cntl.lsitkn_fppci_rega47Mflipflop_rh_2_2a47dffa47w0 ;


		    release `rl_clk_cntl.last_free_phase_pci ;
                    release `rl_clk_cntl.free_clock ;
		    release `rl_clk_cntl.pci_refclk_unbuf_ndly ;
		    release `rl_clk_cntl.pci_refclk_unbuf ;
		    release `rl_clk_cntl.pci_refclk_unbuf_ ;

		end

		begin


		    // Wait for the reset state machine to reset, then de-assert
		    @(posedge (rst_initialized_l===1'b0))
// Wait 15 clock cycles
                repeat (15) @(posedge Mclocks.clock) ;
 
			#1 Msystem.input_reset_l = 1 ;
			// release pci reset for 2.0
			if (ext_clk2 && pll_byp_l)
				release Msystem.RSTnn;

`ifdef STOP_ON_RESET
		    // Special power-up sequence for scan testing:
		    // Stop issuing clocks when rst_cntl has reached the
		    // clocks stopped state
		    @(posedge `rl_clk_cntl.stopped)
			Mclocks.cycles.n = 0 ;
`else
		    // Re-assert trst so clocks don't stop at the end of reset
		    Msystem.jtag_trst_l = 0 ;

		    // Stop issuing clocks when rst_cntl has deasserted its
		    //     outputs and ss_clock is brought low for the first
		    //     non-reset clock edge.
		    @(negedge `SS_SCOPE.reset)
			@(negedge Msystem.clock)
			Mclocks.cycles.n = 0 ;
`endif
		end
	    join

	    // It's now right before the first posedge clock in which the
	    //     internal reset is de-asserted.

`ifdef NOFORCE
`else
	    // Release the held nets
	    if (init_iu) begin
		release `IU.iuchip.exec.tbr_mod.hld_tt ;
		release `IU.iuchip.exec.tbr_mod.tbr_unwr_wire ;
		release `IU.iuchip.exec.wim_mod.wimm ;
		release `IU.iuchip.exec.y_mod.ym ;
		release `IU.iuchip.exec.psr_mod.cc_mod.cc_next ;
		release complete.cc_w_out ;
		release `IU.iuchip.exec.psr_mod.cwp_mod.ncwp ;
		release complete.ncwp ;
		release `IU.iuchip.exec.psr_mod.pil_master_mux_out ;
		release `IU.iuchip.exec.psr_mod.result[12] ;
		release `IU.iuchip.exec.psr_mod.result[13] ;
		release `IU.iuchip.exec.psr_mod.hld_pilefec ;
		release `IU.iuchip.exec.psr_mod.ps_mod.nps ;
		release `SSPARC_CORE.pipe_hold4ic ;
	    end
`endif

	end
    endtask

    // Initialize the PCR to the given value.
`ifdef NOFORCE
`else 
    task init_pcr ;
	// Initial PCR value
	input [31:0] pcr ;
	begin
	    // Assign to the reg which drives the PCR output nets.  This
	    //     reg is clock enabled whenever the IU pipe is not held.
	    `MMU.MMU_cntl.mmu_regs.mmu_cr_out = {
		pcr[23],	// ST
		pcr[22],	// WP
		pcr[21],	// BF
		pcr[20:19],	// PMC
		pcr[18],	// PE
		pcr[17],	// PC
		pcr[16],	// AP
		pcr[15],	// AC
		~pcr[14],	// ~BM
		pcr[13:10],	// RFR CNTL
		pcr[9],		// IE
		pcr[8],		// DE
		pcr[7],		// Superviosr cache allocate disable
		pcr[1],		// NF
		pcr[0] 		// EN
	    } ;

	    // Assign to the regs which drive the inputs of the
	    //     above reg.  These regs are strobed on PCR writes.
	    `MMU.MMU_cntl.mmu_regs.mmu_cr_rega = {
		`MMU.MMU_cntl.mmu_regs.mmu_cr_out[18:10],
		`MMU.MMU_cntl.mmu_regs.mmu_cr_out[8:5],
		`MMU.MMU_cntl.mmu_regs.mmu_cr_out[2:1]
	    } ;
	    `MMU.MMU_cntl.mmu_regs.mmu_cr_regw = {
		`MMU.MMU_cntl.mmu_regs.mmu_cr_out[9],
		`MMU.MMU_cntl.mmu_regs.mmu_cr_out[4:3],
		`MMU.MMU_cntl.mmu_regs.mmu_cr_out[0]
	    } ;
	end
    endtask
`endif


// Tasks to dump memory.

    // Virtual-to-physical translation
    function [31:0] phys ;
	input [31:0] cid ;
	input [31:0] virt_adr ;
	begin
	    // For now, phys=virt
	    phys = virt_adr ;
	end
    endfunction

   // Task to display a word.  It displays either as four hex bytes,
   //    or as a dis-assembled opcode
   task dispwd ;
      input disassemble ;
      input [1:0] mem_type ;
      input [31:0] adr ;
      input begin_line ;
      input begin_block ;
      reg [31:0] word ;
      reg dummy ;
      begin
	 word = read_mem(mem_type, adr) ;

	 // Display opcode if specified (unless parity is bad)
	 if (disassemble) begin
	    $write("%x: %x	", padr(mem_type, adr), word) ;
	    if (^word===1'bx) $display ;
	    else dummy = $disassemble(word, 0) ;
	 end
	 else begin
	    if (begin_line) begin
		if (begin_block) $write("%x: ", padr(mem_type, adr)) ;
		else $write("          ") ;
	    end
	    $write(" %h %h %h %h ",
		word[31:24], word[23:16], word[15:8], word[7:0]) ;
	 end
      end
   endtask

   function [31:0] read_mem ;
	input [1:0] mem_type ;
	input [31:0] mem_adr ;
	reg [31:0] adr, a ;
	reg [32:0] sparse_mem_adr; // need 33 bits sparse memory model
	reg [63:0] mem_data;	   // temp reg for sparse memory model
	begin
	    case (mem_type)

		// I-Cache
		0: begin
		    // Word-align the virtual address
		    adr = mem_adr & `ic_maxbyte & ~32'b11 ;
		    read_mem =
			{`ICACHE[adr], `ICACHE[adr+1],
			 `ICACHE[adr+2], `ICACHE[adr+3]} ;
		end

		// D-Cache
		1: begin
		    // Word-align the virtual address
		    adr = mem_adr & `dc_maxbyte & ~32'b11 ;
		    read_mem =
			{`DCACHE[adr], `DCACHE[adr+1],
			 `DCACHE[adr+2], `DCACHE[adr+3]} ;
		end

		// Memory
		2: begin
		    // This is a *physical* address, not virtual
		    // Doubleword-align the address
		    adr = mem_adr & ~32'b111 ;
		    sparse_mem_adr =  {1'b0, adr >> 3} ;
		    mem_data = 64'h0;
		    $mem_read(Msystem.TheRam.memHandle, sparse_mem_adr, 8'b11111111, mem_data) ;
//		    $display("sp_a:%h", sparse_mem_adr, "m_data:%h ", mem_data);
		    if (mem_adr[2]) begin
			// Odd-word RAM
			read_mem = mem_data[31:0] ;
		    end
		    else begin
			// Even-word RAM
			read_mem = mem_data[63:32] ;
		    end
		end

	    endcase
	end
    endfunction

 
    // Return the address held in a cache tag at a virtual address.
    // For mem_type==2 (memory), just return tha address we were called with.
    function [31:0] padr ;
	input [1:0] mem_type ;
	input [31:0] adr ;

	reg [31:0] tag ;
	begin
	    padr = 0 ; // clear unused bits
	    case (mem_type)
		0: begin
			padr[(`it_lspa-1):0] = adr[(`it_lspa-1):0] ;
			tag = `ITAG[(adr>>`log2_iblksize)&`it_maxblks] ;
			padr[(`it_msb+`it_lspa):`it_lspa]
			    // LSB of ITag is hard-wired to 0
			    = tag[`dt_msb:1] ;
		    end
		1: begin
			padr[(`dt_lspa-1):0] = adr[(`dt_lspa-1):0] ;
			tag = `DTAG[(adr>>`log2_dblksize)&`dt_maxblks] ;
			padr[(`dt_msb+`dt_lspa):`dt_lspa]
			    = tag[`dt_msb:0] ;
		    end
		2: begin
			padr = adr ;
		    end
	    endcase
	end
    endfunction

    // Task to display tlb entries
    //   dtlb(<start_adr>, <#_of_entries>) ;
    // take out conditional don't compile when gate level MMU -bih
    task dtlb ;
	input [31:0] start_adr, n_entries ;
	reg [5:0] adr ;
	reg [41:0] tlb_tag ;
	reg [27:0] tlb_data;
	reg [8:0] index1;
	reg [7:0] context ;
	reg [5:0] index2, index3; 
	reg [2:0] lvl ;
	reg valid_bit, lvl_1, lvl_2, lvl_3 , supervisor, io_pte, ptp_bit ;	
	reg ue, ur, uw, se, sr, sw ;
	reg [18:0] ppn;
	reg [22:0] ptp;
	reg m_bit_tag, c_bit, m_bit, r_bit, w_bit;
	reg [2:0] acc;

	begin
	    adr = start_adr ;  // Truncate to 6 bits
	    repeat (n_entries) begin

// added this to allow to work on gate level simulations -bih
`ifdef MMU_GATE_LEVEL
		// gate level tlb paths
                case(adr)
                  0: tlb_tag = `mc_tlb.TLB_cam.tag00_out;
                  1: tlb_tag = `mc_tlb.TLB_cam.tag01_out;
                  2: tlb_tag = `mc_tlb.TLB_cam.tag02_out;
                  3: tlb_tag = `mc_tlb.TLB_cam.tag03_out;
                  4: tlb_tag = `mc_tlb.TLB_cam.tag04_out;
                  5: tlb_tag = `mc_tlb.TLB_cam.tag05_out;
                  6: tlb_tag = `mc_tlb.TLB_cam.tag06_out;
                  7: tlb_tag = `mc_tlb.TLB_cam.tag07_out;
                  8: tlb_tag = `mc_tlb.TLB_cam.tag08_out;
                  9: tlb_tag = `mc_tlb.TLB_cam.tag09_out;
                  10: tlb_tag = `mc_tlb.TLB_cam.tag10_out;
                  11: tlb_tag = `mc_tlb.TLB_cam.tag11_out;
                  12: tlb_tag = `mc_tlb.TLB_cam.tag12_out;
                  13: tlb_tag = `mc_tlb.TLB_cam.tag13_out;
                  14: tlb_tag = `mc_tlb.TLB_cam.tag14_out;
                  15: tlb_tag = `mc_tlb.TLB_cam.tag15_out;
                  16: tlb_tag = `mc_tlb.TLB_cam.tag16_out;
                  17: tlb_tag = `mc_tlb.TLB_cam.tag17_out;
                  18: tlb_tag = `mc_tlb.TLB_cam.tag18_out;
                  19: tlb_tag = `mc_tlb.TLB_cam.tag19_out;
                  20: tlb_tag = `mc_tlb.TLB_cam.tag20_out;
                  21: tlb_tag = `mc_tlb.TLB_cam.tag21_out;
                  22: tlb_tag = `mc_tlb.TLB_cam.tag22_out;
                  23: tlb_tag = `mc_tlb.TLB_cam.tag23_out;
                  24: tlb_tag = `mc_tlb.TLB_cam.tag24_out;
                  25: tlb_tag = `mc_tlb.TLB_cam.tag25_out;
                  26: tlb_tag = `mc_tlb.TLB_cam.tag26_out;
                  27: tlb_tag = `mc_tlb.TLB_cam.tag27_out;
                  28: tlb_tag = `mc_tlb.TLB_cam.tag28_out;
                  29: tlb_tag = `mc_tlb.TLB_cam.tag29_out;
                  30: tlb_tag = `mc_tlb.TLB_cam.tag30_out;
                  31: tlb_tag = `mc_tlb.TLB_cam.tag31_out;
//                  32: tlb_tag = `mc_tlb.TLB_cam.tag32_out;
//                  33: tlb_tag = `mc_tlb.TLB_cam.tag33_out;
//                  34: tlb_tag = `mc_tlb.TLB_cam.tag34_out;
//                  35: tlb_tag = `mc_tlb.TLB_cam.tag35_out;
//                  36: tlb_tag = `mc_tlb.TLB_cam.tag36_out;
//                  37: tlb_tag = `mc_tlb.TLB_cam.tag37_out;
//                  38: tlb_tag = `mc_tlb.TLB_cam.tag38_out;
//                  39: tlb_tag = `mc_tlb.TLB_cam.tag39_out;
//                  40: tlb_tag = `mc_tlb.TLB_cam.tag40_out;
//                  41: tlb_tag = `mc_tlb.TLB_cam.tag41_out;
//                  42: tlb_tag = `mc_tlb.TLB_cam.tag42_out;
//                  43: tlb_tag = `mc_tlb.TLB_cam.tag43_out;
//                  44: tlb_tag = `mc_tlb.TLB_cam.tag44_out;
//                  45: tlb_tag = `mc_tlb.TLB_cam.tag45_out;
//                  46: tlb_tag = `mc_tlb.TLB_cam.tag46_out;
//                  47: tlb_tag = `mc_tlb.TLB_cam.tag47_out;
//                  48: tlb_tag = `mc_tlb.TLB_cam.tag48_out;
//                  49: tlb_tag = `mc_tlb.TLB_cam.tag49_out;
//                  50: tlb_tag = `mc_tlb.TLB_cam.tag50_out;
//                  51: tlb_tag = `mc_tlb.TLB_cam.tag51_out;
//                  52: tlb_tag = `mc_tlb.TLB_cam.tag52_out;
//                  53: tlb_tag = `mc_tlb.TLB_cam.tag53_out;
//                  54: tlb_tag = `mc_tlb.TLB_cam.tag54_out;
//                  55: tlb_tag = `mc_tlb.TLB_cam.tag55_out;
//                  56: tlb_tag = `mc_tlb.TLB_cam.tag56_out;
//                  57: tlb_tag = `mc_tlb.TLB_cam.tag57_out;
//                  58: tlb_tag = `mc_tlb.TLB_cam.tag58_out;
//                  59: tlb_tag = `mc_tlb.TLB_cam.tag59_out;
//                  60: tlb_tag = `mc_tlb.TLB_cam.tag60_out;
//                  61: tlb_tag = `mc_tlb.TLB_cam.tag61_out;
//                  62: tlb_tag = `mc_tlb.TLB_cam.tag62_out;
//                  63: tlb_tag = `mc_tlb.TLB_cam.tag63_out;
                endcase
 
                tlb_data = `mc_tlb.TLB_ram.tlb_data[adr];

`else
`ifdef RTL_TLB

                case(adr)
                  0: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag00_out;
                  1: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag01_out;
                  2: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag02_out;
                  3: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag03_out;
                  4: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag04_out;
                  5: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag05_out;
                  6: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag06_out;
                  7: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag07_out;
                  8: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag08_out;
                  9: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag09_out;
                  10: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag10_out;
                  11: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag11_out;
                  12: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag12_out;
                  13: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag13_out;
                  14: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag14_out;
                  15: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag15_out;
                  16: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag16_out;
                  17: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag17_out;
                  18: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag18_out;
                  19: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag19_out;
                  20: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag20_out;
                  21: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag21_out;
                  22: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag22_out;
                  23: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag23_out;
                  24: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag24_out;
                  25: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag25_out;
                  26: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag26_out;
                  27: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag27_out;
                  28: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag28_out;
                  29: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag29_out;
                  30: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag30_out;
                  31: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag31_out;
//                  32: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag32_out;
//                  33: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag33_out;
//                  34: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag34_out;
//                  35: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag35_out;
//                  36: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag36_out;
//                  37: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag37_out;
//                  38: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag38_out;
//                  39: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag39_out;
//                  40: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag40_out;
//                  41: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag41_out;
//                  42: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag42_out;
//                  43: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag43_out;
//                  44: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag44_out;
//                  45: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag45_out;
//                  46: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag46_out;
//                  47: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag47_out;
//                  48: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag48_out;
//                  49: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag49_out;
//                  50: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag50_out;
//                  51: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag51_out;
//                  52: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag52_out;
//                  53: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag53_out;
//                  54: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag54_out;
//                  55: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag55_out;
//                  56: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag56_out;
//                  57: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag57_out;
//                  58: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag58_out;
//                  59: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag59_out;
//                  60: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag60_out;
//                  61: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag61_out;
//                  62: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag62_out;
//                  63: tlb_tag = `MMU.MMU_tlb.TLB_cam.tag63_out;
                endcase
 
                tlb_data = `MMU.MMU_tlb.TLB_ram.tlb_data[adr];

`else

		tlb_tag  = `MMU.MMU_tlb.tlb_tag[adr];
		tlb_data = `MMU.MMU_tlb.tlb_data[adr];
`endif


`endif

		    valid_bit 	= tlb_tag[ 41];
		    lvl_1	= tlb_tag[ 40];
		    index1	= tlb_tag[ 39:32];
		    lvl_2	= tlb_tag[ 31];
		    index2	= tlb_tag[ 30:25];
		    lvl_3	= tlb_tag[ 24];
		    index3	= tlb_tag[ 23:18];
		    context	= tlb_tag[ 17:10];
		    ue		= tlb_tag[ 9];
		    ur		= tlb_tag[ 8];
		    uw		= tlb_tag[ 7];
		    se		= tlb_tag[ 6];
		    sr		= tlb_tag[ 5];
		    sw		= tlb_tag[ 4];
		    supervisor	= tlb_tag[ 3];
		    io_pte	= tlb_tag[ 2];
		    ptp_bit	= tlb_tag[ 1];
		    m_bit_tag	= tlb_tag[ 0];


		    lvl		= tlb_data[ 27:25];
		    ppn		= tlb_data[ 24:6];
		    c_bit	= tlb_data[ 5];
		    m_bit	= tlb_data[ 4];
		    r_bit	= tlb_data[ 3];
		    acc		= tlb_data[ 2:0];
		    w_bit	= tlb_data[ 0];
		    ptp		= tlb_data[24:2];

	   	$write("ent:%h v:%b vpn:%h lvl:%h s:%b io:%b p:%b cxt:%h        ", 
			adr, valid_bit, {index1, index2, index3}, 
			{lvl_1, lvl_2, lvl_3}, supervisor, io_pte, 
			ptp_bit,context); 
	
		case ({valid_bit, io_pte, ptp_bit})
			3'b100: begin		// valid, pte
				$display("ppn:%h c:%b m:%b r:%b acc:%h (pte)",
					ppn, c_bit, m_bit, r_bit, acc);
				end
			3'b101: begin		// valid, ptp
				$display("ptp:%h (ptp)", ptp);
				end
			3'b110: begin		// valid, io_pte 
				$display("ppn:%h w:%b (io_pte)", 
					ppn, w_bit);
				end
			3'b111: begin		// illegal, (io_ptp?)
				$display("vptp:%h (ptp)", ptp);
				end
			3'b000, 3'b001, 3'b010, 3'b011, 3'b0xx: begin
				$display("(..inv..)");
				end
			default: begin	
				$display("(..xxx..)");
				end
			endcase
		adr = adr + 1;
	    end
	end
    endtask


    // Task to display 32-byte blocks of memory
    //   dmemn(<dcache/icache>, <start_adr>, <#_of_blocks>, <disassemble>) ;
    task dmemn ;
	input [1:0] mem_type ;
	input [31:0] start_adr, n_blocks ;
	input disassemble ;

	reg [31:0] adr, stopadr ;
	reg [31:0] cid ;
	integer line ;
	reg [31:0] blocksize, maxbyte ;
	reg [31:0] tag, pa ;
	reg [31:0] mem_lbl ;
	reg [71:0] vhdr ;
	reg [4:0] supv_lvl ;

	begin
	    case (mem_type)
		0: begin
			mem_lbl = "I VA" ;
			vhdr = "V S Ctx L" ;
			blocksize = `ic_blksize ;
			maxbyte = `ic_maxbyte ;
		    end
		1: begin
			mem_lbl = "D VA" ;
			vhdr = "V A Ctx  " ;
			blocksize = `dc_blksize ;
			maxbyte = `dc_maxbyte ;
		    end
		2: begin
			mem_lbl = "M PA" ;
			vhdr = "" ;
			blocksize = 32 ;
			maxbyte = `main_mem_size-1 ;
		    end
	    endcase

	    adr = start_adr & ~(blocksize-1) ;

	    $write("--%s--", mem_lbl) ;
	    if (disassemble) $display ;
	    else $display(
		"    0  1  2  3   4  5  6  7   8  9  a  b   c  d  e  f   %0s",
		vhdr) ;

	    repeat (n_blocks) begin
		adr = adr & maxbyte ;
		stopadr = adr + blocksize ;
		line = 1 ;
		while (adr < stopadr) begin

		    dispwd(disassemble, mem_type, adr, 1, (line==1)) ;
		    dispwd(disassemble, mem_type, adr+4, 0, 0) ;
		    dispwd(disassemble, mem_type, adr+8, 0, 0) ;
		    dispwd(disassemble, mem_type, adr+12, 0, 0) ;

		    if (!disassemble) begin
			if (line==1) case (mem_type)

			    // ITag
			    0: begin
				supv_lvl = `ITAGA[adr/blocksize] ;
				$write("  %b %b %h  %h",
					    `ITAGV[adr/blocksize],
					    supv_lvl[3],
					    `ITAGC[adr/blocksize],
					    supv_lvl[1:0]
				    ) ;
				end

			    // DTag
			    1: $write("  %b %0h %h",
					`DTAGV[adr/blocksize],
					acc_decode(`DTAGA[adr/blocksize]),
					`DTAGC[adr/blocksize]
				) ;
			endcase

			$display("") ;
		    end

		    adr = adr + 16 ;
		    line = line + 1 ;
		end
	    end
	end
    endtask

    // Decode the encoded ACC field from a cache tag
    function [2:0] acc_decode ;
    input [4:0] encoded_acc ;
	acc_decode = 
	    (encoded_acc==5'h06) ? 0 : (
	    (encoded_acc==5'h02) ? 1 : (
	    (encoded_acc==5'h04) ? 2 : (
	    (encoded_acc==5'h00) ? 3 : (
	    (encoded_acc==5'h01) ? 4 : (
	    (encoded_acc==5'h10) ? 5 : (
	    (encoded_acc==5'h0c) ? 6 : (
	    (encoded_acc==5'h08) ? 7 : (
	    3'bx )))))))) ;
    endfunction

   // Task to alter Tag values
   task altertag ;
      input [1:0] mem_type ;
      input [31:0] a,v,n ;
      integer foo, adr, stopadr, blocksize, tag_adr ;
      reg [7:0] cid ;  // Should be an input?
      reg [4:0] encoded_acc ;  // Should be an input?
      reg [31:0] phys_adr ;
      reg [`dt_msb:0] dtva ;
      reg [`it_msb:0] itva ;
      begin

	 // These should be supplied as inputs
	 cid = 0 ;
	 encoded_acc = 0 ;

	 blocksize = mem_type[0] ? `dc_blksize : `ic_blksize ;
	 stopadr=a+(n*blocksize) ;
	 if (n>1) $write("Initializing %c-tags %h through %h . . . ",
			   mem_type[0] ? "D" : "I",
			   a,stopadr-blocksize);
	 for (adr=a;(adr===a)||(adr<stopadr);adr=adr+blocksize) begin
	    phys_adr = phys(cid,adr) ;
	    if (mem_type) begin
		tag_adr = (adr >> `log2_dblksize) & `dt_maxblks ;
		dtva = phys_adr>>`dt_lspa ;
		`DTAG[tag_adr] = dtva ;
		`DTAGC[tag_adr] = cid ;
		`DTAGA[tag_adr] = encoded_acc ;
		// Don't change V-bit unless 0 or 1 is specified
		if ((v & ~1)===0) `DTAGV[tag_adr] = v ;
	    end
	    else begin
		tag_adr = (adr >> `log2_iblksize) & `it_maxblks ;
		itva = phys_adr>>`it_lspa ;
		// LSB of ITag is 0.
		`ITAG[tag_adr] = {itva,1'b0} ;
		`ITAGC[tag_adr] = cid ;
		`ITAGA[tag_adr] = encoded_acc ;
		// Don't change V-bit unless 0 or 1 is specified
		if ((v & ~1)===0) `ITAGV[tag_adr] = v ;
	    end
	 end
	 if (n>1) $display("done");
      end
   endtask

    function tag_match ;
	input [1:0] mem_type ;
	input [31:0] cid ;
	input [31:0] virt_adr ;
	reg [31:0] pcr ;
	reg cache_enabled, tag_valid ;
	begin
	    // Check PCR to see if this cache is enabled.
`ifdef MMU_GATE_LEVEL
/*  changed to match Seagle synthesis netlist. 6/22/98. 
	    pcr[15] = `m_mmu_cntl.mmu_regs_mmu_cr_19_MflipflopR_18_10_dff.Q;
	    pcr[9]  = `m_mmu_cntl.mmu_regs_mmu_cr_19_MflipflopR_18_4_dff.Q;
	    pcr[8]  = `m_mmu_cntl.mmu_regs_mmu_cr_19_MflipflopR_18_3_dff.Q;
	    pcr[0]  = `m_mmu_cntl.mmu_regs_mmu_cr_19_MflipflopR_18_0_dff.Q;
*/
            pcr[15] = `m_mmu_cntl.mmu_regs.mmu_cr[15];
            pcr[9]  = `m_mmu_cntl.mmu_regs.mmu_cr[9];
            pcr[8]  = `m_mmu_cntl.mmu_regs.mmu_cr[8];
            pcr[0]  = `m_mmu_cntl.mmu_regs.mmu_cr[0];

`else
  	    pcr = `MMU.pcr ;
`endif
	    cache_enabled = 
		(pcr[0] | pcr[15]) // mmu_en or alt_cacheablity
		& (mem_type[0] ? pcr[8] : pcr[9])
		;

	    tag_valid = mem_type[0]
		    ? `DTAGV[(virt_adr >> `log2_dblksize) & `dt_maxblks]
		    : `ITAGV[(virt_adr >> `log2_iblksize) & `it_maxblks]
		    ;

	    tag_match =
		cache_enabled & tag_valid
		    & ( phys(cid, virt_adr) == padr(mem_type, virt_adr) )
		    ;

	    if (~cache_enabled && tag_valid) begin
		$display(
		 "\n### tag_match: %s-cache disabled but tag valid at virtual address %h",
		     mem_type[0] ? "D" : "I",
		     virt_adr) ;
		Mclocks.warning_count = Mclocks.warning_count + 1 ;
	    end
	end
    endfunction

    // Get the addressed word from memory.
    function [31:0] getword ;
	input nomem ;
	input [31:0] cid ;
	input [31:0] virt_adr ;

	reg imatch, dmatch ;
	reg [31:0] iword, dword, mword ;


	begin
 
	    if (nomem) mword = 32'bx ;
	    else mword = read_mem(2, phys(cid, virt_adr)) ;
// ******
//	force imatch to 0 for now to disable icache - dcache - mem
//	checking.
//	we'll eventually want to do this via a switch and
//	variable in vfront!!!!
//
//	    imatch = tag_match(0, cid, virt_adr) ;
	    imatch = 0;
	    dmatch = tag_match(1, cid, virt_adr) ;

	    if (dmatch) begin
		dword = read_mem(1, virt_adr) ;
		if (~nomem && (dword !== mword)) begin
		    $display(
		     "\n### getword: mismatch: D-cache=%h, Memory=%h at %h in Context %0h",
			 dword, mword,
			 virt_adr, cid) ;
		    Mclocks.warning_count = Mclocks.warning_count + 1 ;
		end
	    end

	    if (imatch) begin
		iword = read_mem(0, virt_adr) ;
		if (~nomem && (iword !== mword)) begin
		    $display(
		     "\n### getword: mismatch: I-cache=%h, Memory=%h at %h in Context %0h",
			 iword, mword,
			 virt_adr, cid) ;
		    Mclocks.warning_count = Mclocks.warning_count + 1 ;
		end
	    end

	    case ({imatch, dmatch})
		2'b01: begin
		    getword = dword ;
		end
		2'b10: begin
		    getword = iword ;
		end
		2'b11: begin
		    getword = dword ;
		    if (dword !== iword) begin
			$display(
			 "\n### getword: mismatch: I-cache=%h, D-cache=%h at %h in Context %0h",
			     iword, getword,
			     virt_adr, cid) ;
			Mclocks.warning_count = Mclocks.warning_count + 1 ;
		    end
		end
		2'b00: begin
		    getword = mword ;
		end
		default: begin
		    $display(
			 "\n*** getword: I-tagmatch=%b, D-tagmatch=%b at %h in Context %0h",
			 imatch, dmatch,
			 virt_adr, cid) ;
		    Mclocks.error_count = Mclocks.error_count + 1 ;
		    getword = 32'bx ;
		end
	    endcase
	end
    endfunction
 
   // Task to dump memory in SAS format.
   //   Takes a virtual address and context ID.
   task mdump ;
      input nomem ;
      input [31:0] cid ;
      input [31:0] start_wd, stop_wd, boot_wd ;
      reg [31:0] start_adr, stop_adr, virt_adr, word ;
      reg [31:0] dumpfile ;

      begin
         start_adr = start_wd*4 ;
         stop_adr = stop_wd*4 ;
         $write("Dumping Virtual locations %h:%h in Context %0h . . . ",
                           start_adr, stop_adr+3, cid) ;
         dumpfile = $fopen({Mclocks.working_dir,"/mdump.v"}) ;
 
         // Now dump from cache/memory
         for (virt_adr=start_adr ;
               virt_adr <= stop_adr ;
               virt_adr = virt_adr+4 ) begin 
	    word = getword(nomem, cid, virt_adr) ;
	    $fdisplay(dumpfile, "      0x%h", word) ;
         end
         $fclose(dumpfile) ;
         $display("done");
      end
   endtask

 
   // Task to compare a range of virtual memory in a given context
   //    to the pattern written by adrinit.
   task wbcomp ;
      input nomem ;
      input [31:0] start_wd, stop_wd ;
      input [6:0] cid ;

      reg [31:0] start_adr, stop_adr, virt_adr ;
      reg [31:0] compfile ;
      reg [31:0] word ;
      reg [15:0] va, va2 ;
      reg [31:0] err_count ;

      begin
         start_adr = start_wd*4 ;
         stop_adr = stop_wd*4 ;
         err_count = 0 ;
         $display("Checking Virtual locations %h:%h in Context %h . . . ",
                           start_adr, stop_adr+3, cid) ;
         compfile = $fopen({Mclocks.working_dir,"/wb.comp"}) ;

         for (virt_adr=start_adr ;
               virt_adr <= stop_adr ;
               virt_adr = virt_adr+4 ) begin
            va = virt_adr ;
            va2 = virt_adr+2 ;
            word = getword(nomem, cid, virt_adr) ;


	    // **** changed {va, va2} to ffffffff
	    // 		Changes needed to work with new sparse memory
	    //		model.  The sparse memory model initializes
	    //		unused locations to 'ffffffff'...
	    //	note 2:  switched it to 'h0 until IU fixed

            if (word !== 'h0 ) begin
               $fdisplay(compfile|1, "*** wbcomp: %h had 0x%h, should be 0x%h in Context %h",
                                       virt_adr, word,'h00000000 , cid) ;
               err_count = err_count + 1 ;
            end
         end
         $fclose(compfile) ;
Next12
HierarchyFilesModulesSignalsTasksFunctionsHelp

This page: Created:Thu Aug 19 12:00:49 1999
From: ../../../sparc_v8/env/rtl/task.v

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