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:  @(#)rl_tw_sm.v
***
****************************************************************************
****************************************************************************/
//***************************************************************************
// @(#)rl_tw_sm.v	1.109 5/15/94
// rl_tw_sm.v
//
//  Description:
//      Preprocessed MMU Table Walk State Machine
//
//  Dependencies: Always..
//
//***************************************************************************

    /* functional model of MMU table walk state machine */

[Up: m_mmu_cntl tw_sm]
module rl_tw_sm(
    root_tw,
    pt1_tw,
    pt2_tw,
    tw_done,
    io_s_bit,
    tw_abort,
    tw_tlb_vbit,
    tw_io_bit,
    lvl_probe_hld,
    tlb_cam_reload,
    co_in,
    tw_rewrite_cam,
    ldtlb_data_tw,
    ldtlb_tag_tw,
    va_sel_par_in,
    tw_read_req,
    read_word_mreq,
    tw_write_req,
    m_in,
    ptp_in,
    va_s_in,
    tlb_ram_lvl,
    tlb_cam_lvl,
    tw_tlb_nxt,
    tw_sm_lvl,
    tw_err_lvl,
    ld_par_tw,
    tw_init_par,
    ld_mreq_tw,
    tlb_flush,
    r_flush_entry,
    tlb_update,
    tw_trcr_hld,
    tw_addr_err,
    tw_xlat_err,
    tw_prb_drdy,
    tw_prb_err,
    probe_invalid,
    probe_done,
    flush_done,
    tw_sin,
    tw_pte_chk,
    io_tw_wrt,
    sr_tw_wrt,
    cam_reg_hld,
    ram_reg_hld,
    asi_cam_read,
    asi_ram_read,

/*** Inputs ***/
    io_tlb_tw,
    io_tlb,
    dvma_req_x,
    set_m_on_tw,
    strt_tw_for_m,
    mdata_in_et,
    mdata_in_acc,
    mdata_in_r,
    mdata_in_m,
    tlb_miss,
    asi_done,
    mmstben,
    virt_ptp2,
    mmdaten,
    mc_mstb_l,
    st_miss_x,
    r_dc_tlb,
    dc_tlb_tw,
    flush_tlb_pte,
    flush_tlb_seg,
    flush_tlb_reg,
    flush_tlb_ctx,
    flush_tlb_all,
    flush_iopte,
    flush_ioall,
    probe_err,
    probe,
    flush,
    probe_entire,
    probe_lvl0,
    probe_lvl1,
    probe_lvl2,
    probe_lvl3,
    r_acc_err_tw,
    mm_misc2cf,
    tw_perr,
    r_tw_err,
    tw_par,
    mmu_asi_op,
    r_trap_w,
    sb_data_avail,
    enbl_soft_tw,
    ss_clock,
    ss_reset);


output root_tw;   	// rootmem or rootwrt
output pt1_tw;   	// pt1mem or pt1wrt
output pt2_tw;   	// pt2mem or pt2wrt
output tw_done;   	// indicates that table walk is done
output tw_abort;   	// indicates table walk was aborted because of dvma_req
output lvl_probe_hld;   // hold PTP/PTE coming from memory
output tw_tlb_vbit;   	// tlb v bit for tw write to tlb
output tw_io_bit;   	// tlb io_bit
output tlb_cam_reload;  // wrap cam_reg back onto cam_data_in
output co_in;   	// indicates compare override
output tw_rewrite_cam;  // indicates that table walk will rewrite CAM for L1,L2 PTE
output ldtlb_data_tw;   // indicates that tlb data is written with ptp or pte
output ldtlb_tag_tw;    // indicates that tlb tag is written with ptp or pte
output va_sel_par_in;  // indicates that PAR is TLB tag input next cycle
output tw_read_req;       // memory read of word at address in par required
output read_word_mreq;  // early mem read of word at address in par required
output tw_write_req;      // memory write of word at address in par required
output m_in;            // modified bit location input to ram (bit 6)
output ptp_in;          // ptp bit input to ram
output va_s_in;         // superviosr bit input to cam
output io_s_bit;         // superviosr bit input to cam
output [2:0] tlb_ram_lvl;  // level field input to ram
output [2:0] tlb_cam_lvl;  // level field input to cam
output tw_tlb_nxt;      // tlb being used for table walk next cycle
output [1:0] tw_sm_lvl; // level of tablewalk 
output [1:0] tw_err_lvl; // level of tablewalk during error
output ld_par_tw;       // ld par signal during table walk 
output tw_init_par;     // CTPR/IBAR select
output ld_mreq_tw;      // ld mreq signal during table walk 
output tlb_flush;    // TLB flush control signal for PTE flushes
output r_flush_entry;   // TLB flush last cycle
output tlb_update;      // TLB update from read word in progress
output tw_trcr_hld;     // Hold TRCR register value during TAG update
output tw_addr_err;     // interanl address error detected.
output tw_xlat_err;     // translation error detected.
output tw_prb_drdy;     // Probe data ready next cycle.
output tw_prb_err;      // Probe error during tablewalk
output probe_invalid;   // Invalid Probe entry 
output probe_done;      // Probe done
output flush_done;      // flush done
output tw_sin;          // Tablewalk CAM Supervisor input bit
output tw_pte_chk;      // Tablewalk PTE privelege/protection check state
output io_tw_wrt;       // IO Tablewalk sm write state
output sr_tw_wrt;       // IU Tablewalk sm write state
output cam_reg_hld;     // TLB CAM output register hold
output ram_reg_hld;     // TLB RAM output register hold

input asi_cam_read;     // hold cam shadow for asi read
input virt_ptp2;     // 
input dc_tlb_tw;     // 
input dvma_req_x;     // 
input asi_ram_read;     // hold ram shadow register for asi read
input io_tlb_tw;       // IO TLB reference next (and current in tw) cycle 
input io_tlb;       // IO TLB reference next (and current in tw) cycle 
input set_m_on_tw;      // set modified bit on a table walk due to write op
input strt_tw_for_m;    // set modified bit on a table walk due to write op
input [1:0] mdata_in_et;    // et field of incoming data (bits [1:0])
input [1:0] mdata_in_acc;    // acc[2:1] field of incoming data (bits [4:3])
input mdata_in_r;       // r field of incoming data (bit 5)
input mdata_in_m;       // m field of incoming data (bit 6)
input tlb_miss;         // tlb miss this cycle
input mmstben;          // next mc_mstb_l means mmu data is ready
input mmdaten;          // means that write has started.
input mc_mstb_l;        // input mdata strobe from mcb
input r_dc_tlb;
input st_miss_x;
input asi_done;
input flush_tlb_pte;    // ASI decode for PTE flush
input flush_tlb_seg;    // ASI decode for SEG flush
input flush_tlb_reg;    // ASI decode for REG flush
input flush_tlb_ctx;    // ASI decode for CTX flush
input flush_tlb_all;    // ASI decode for ALL flush
input flush_iopte;      // Control space decode for PTE flush
input flush_ioall;      // Control space decode for PTE flush
input probe_err;
input flush;
input probe;
input probe_entire;
input probe_lvl0;
input probe_lvl1;
input probe_lvl2;
input probe_lvl3;
input r_acc_err_tw;
input mm_misc2cf;
input tw_perr;
input r_tw_err;
input tw_par;           // par cntl in TLB_TW state
input mmu_asi_op;       // par cntl in ASI_OP state
input r_trap_w;
input sb_data_avail;
input enbl_soft_tw;
input ss_clock;         // input clock
input ss_reset;         // input reset

    wire [29:0] state; 
//  state names
// The Msb is intended to be the table walk indicator.


parameter        IDLE          =   0,
                 INIT_PAR      =   1,
                 INIT_PAR_MEM  =   2,
                 INIT_PAR_WRT  =   3,
                 ROOT          =   4,
                 RTMEM         =   5,
                 RTWRT         =   6,
                 PTBL1         =   7,
                 PT1MEM        =   8,
                 PT1WRT        =   9,
                 PTBL2         =   10,
                 PT2MEM        =   11,
                 PT2WRT        =   12,
                 PTBL3         =   13,
                 PT3MEM        =   14,
                 PT3WRT        =   15,
                 PTE_TAG       =   16,
                 PTE_TAG_U     =   17,
                 UPDATE        =   18,
                 UPDATE_C      =   19,
                 UPDATE2       =   20,
                 UPDATE_F      =   21,
                 PTE_FLUSH     =   22,
                 PRB_DONE      =   23,
                 PRB_CLR       =   24,
                 ERR_ADR       =   25,
                 ERR_XLT       =   26,
                 VPTP_HIT      =   27,
                 PTE_FLUSH1    =   28,
                 PTE_FLUSH2    =   29;


    wire tdata_rdy_in = ~mc_mstb_l & mmstben;
    wire probe_hit;
    wire lvl_probe_hld;

    wire tdata_rdy;
    Mflipflop_r_1 mc_mstb_reg_1(tdata_rdy,tdata_rdy_in,~ss_reset,ss_clock) ;

    wire r_mdata_in_r ;
    Mflipflop_r_1 mdata_r_reg_1(r_mdata_in_r,mdata_in_r,~ss_reset,ss_clock) ;

    wire r_mmdaten ;
    Mflipflop_r_1 mmdaten_reg_1(r_mmdaten,mmdaten,~ss_reset,ss_clock) ;

    wire r_mdata_in_m ;
    Mflipflop_r_1 mdata_m_reg_1(r_mdata_in_m,mdata_in_m,~ss_reset,ss_clock) ;

    wire [1:0] r_mdata_et;
    Mflipflop_r_2 mdata_et_reg_2(r_mdata_et,mdata_in_et,~ss_reset,ss_clock) ;

    wire [1:0] r_mdata_acc;
    Mflipflop_r_2 mdata_acc_reg_2(r_mdata_acc,mdata_in_acc,~ss_reset,ss_clock) ;

    wire flush_entry = (dc_tlb_tw & ~flush_done & (flush_tlb_pte |
			flush_tlb_seg | flush_tlb_reg | flush_tlb_ctx | 
                       flush_tlb_all)) | 
			(~io_tlb & (flush_iopte | flush_ioall)) ;

    wire dvma_ioflush = io_tlb & (flush_iopte | flush_ioall);

    wire flush_crs = dc_tlb_tw & (flush_tlb_ctx | flush_tlb_reg |
				  flush_tlb_seg) ;

    wire r_flush_entry_in = flush_entry | dvma_ioflush |
			(state[PTE_FLUSH] & flush_crs) |
			(state[PTE_FLUSH1] & virt_ptp2);

    wire r_flush_entry;
    Mflipflop_r_1 flush_entry_ff_1(r_flush_entry,r_flush_entry_in,~ss_reset,ss_clock) ;

    wire ptp_flush_in;
    wire r_ptp_flush;
    wire ptp_flush = ptp_flush_in | (r_ptp_flush & tw_par);
    Mflipflop_r_1 ptp_flush_ff_1(r_ptp_flush,ptp_flush,~ss_reset,ss_clock) ;


//                                          2         1     
//                                    987654321098765432109876543210
parameter [29:0] D_IDLE         = 30'b000000000000000000000000000001,
                 D_INIT_PAR     = 30'b000000000000000000000000000010,
                 D_INIT_PAR_MEM = 30'b000000000000000000000000000100,
                 D_INIT_PAR_WRT = 30'b000000000000000000000000001000,
                 D_ROOT         = 30'b000000000000000000000000010000,
                 D_RTMEM        = 30'b000000000000000000000000100000,
                 D_RTWRT        = 30'b000000000000000000000001000000,
                 D_PTBL1        = 30'b000000000000000000000010000000,
                 D_PT1MEM       = 30'b000000000000000000000100000000,
                 D_PT1WRT       = 30'b000000000000000000001000000000,
                 D_PTBL2        = 30'b000000000000000000010000000000,
                 D_PT2MEM       = 30'b000000000000000000100000000000,
                 D_PT2WRT       = 30'b000000000000000001000000000000,
                 D_PTBL3        = 30'b000000000000000010000000000000,
                 D_PT3MEM       = 30'b000000000000000100000000000000,
                 D_PT3WRT       = 30'b000000000000001000000000000000,
                 D_PTE_TAG      = 30'b000000000000010000000000000000,
                 D_PTE_TAG_U    = 30'b000000000000100000000000000000,
                 D_UPDATE       = 30'b000000000001000000000000000000,
                 D_UPDATE_C     = 30'b000000000010000000000000000000,
                 D_UPDATE2      = 30'b000000000100000000000000000000,
                 D_UPDATE_F     = 30'b000000001000000000000000000000,
                 D_PTE_FLUSH    = 30'b000000010000000000000000000000,
                 D_PRB_DONE     = 30'b000000100000000000000000000000,
                 D_PRB_CLR      = 30'b000001000000000000000000000000,
                 D_ERR_ADR      = 30'b000010000000000000000000000000,
                 D_ERR_XLT      = 30'b000100000000000000000000000000,
                 D_VPTP_HIT     = 30'b001000000000000000000000000000,
                 D_PTE_FLUSH1   = 30'b010000000000000000000000000000,
                 D_PTE_FLUSH2   = 30'b100000000000000000000000000000;


/*** Display routine for tw sm state information.  *****************/
// synopsys translate_off

    reg[30*8:1] tw_state_name;
    always @ state
	if(~ss_reset & (state == 30'b0)) begin
        Mclocks.print_error("TW state = 0  *** BAD TW_STATE ***") ;
            tw_state_name = "*** ALL ZERO *** BAD TW_STATE!";
        end
        else case (state)
                 D_IDLE:         tw_state_name = "[idle] - idle";
                 D_INIT_PAR:     tw_state_name = "[init_par] - Ld PAR";
                 D_ROOT:         tw_state_name = "[root] - Root lookup";
                 D_INIT_PAR_MEM: tw_state_name = "[ioroot] - IO root";
                 D_INIT_PAR_WRT: tw_state_name = "[iorwrt] - IO tlb wrt";
                 D_PTBL1:        tw_state_name = "[ptbl1] - LVL1 lookup";
                 D_PTBL2:        tw_state_name = "[ptbl2] - LVL2 lookup";
                 D_PTBL3:        tw_state_name = "[ptbl3] - LVL3 lookup";
                 D_ERR_ADR:      tw_state_name = "[err_adr] - address error";
                 D_ERR_XLT:      tw_state_name = "[err_xlt] - translate error";
                 D_RTMEM:        tw_state_name = "[rtmem] -  root mem wait";
                 D_RTWRT:        tw_state_name = "[rtwrt] - root tlb update";
                 D_PT1MEM:       tw_state_name = "[pt1mem] - LVL1 mem wait";
                 D_PT1WRT:       tw_state_name = "[pt1wrt] - LVL1 tlb update";
                 D_PT2MEM:       tw_state_name = "[pt2mem] - LVL2 mem wait";
                 D_PT2WRT:       tw_state_name = "[pt2wrt] - LVL2 tlb update";
                 D_PT3MEM:       tw_state_name = "[pt3mem] - LVL3 mem wait";
                 D_PT3WRT:       tw_state_name = "[pt3wrt] - LVL3 tlb update";
                 D_PTE_TAG:      tw_state_name = "[pte_tag] - Fix PTE tag";
                 D_UPDATE:       tw_state_name = "[update] - Read TLB PTE";
                 D_UPDATE_C:     tw_state_name = "[update_c] - Check TLB PTE";
                 D_UPDATE2:      tw_state_name = "[update2] - Update mem PTE";
                 D_UPDATE_F:     tw_state_name = "[update_f] - Flush TLB PTE";
                 D_PTE_TAG_U:    tw_state_name = "[pte_tag_u] - Fix tag/mem";
                 D_PTE_FLUSH:    tw_state_name = "[pte_flush] - Flush Entry";
                 D_PTE_FLUSH1:   tw_state_name = "[pte_flush1] - Flush ptps";
                 D_PTE_FLUSH2:   tw_state_name = "[pte_flush2] - Flush V-ptps";
                 D_PRB_DONE:     tw_state_name = "[prb_done] - Probe Done ";
                 D_PRB_CLR:      tw_state_name = "[prb_clr] - Probe Clear ";
                 D_VPTP_HIT:     tw_state_name = "[vptp_hit] - vptp2 hit ";

        endcase
// synopsys translate_on

/*******************************************************************/


/* function drives ldtlb_tw, ld_par_tw, ld_mreq_tw,
tw_read_req, read_word_mreq, tw_write_req, ptp_in, 
m_in, tw_sm_lvl, ld_par_iotw */

function [29:0] next_tw_state;

    input [29:0] state;   
    input io_tlb_tw;
    input tlb_miss; 
    input dvma_req_x; 
    input r_dc_tlb; 
    input st_miss_x; 
    input virt_ptp2; 
    input tdata_rdy;
    input [1:0] r_mdata_et;
    input flush_crs;
    input r_mdata_in_r;
    input r_mdata_in_m;
    input flush_entry;
    input dvma_ioflush;
    input r_flush_entry;
    input probe;            //All probe siganls become active in the W-stage
    input probe_entire;
    input probe_lvl0;
    input probe_lvl1;
    input probe_lvl2;
    input probe_lvl3;
    input set_m_on_tw;
    input strt_tw_for_m;
    input r_mmdaten;
    input r_acc_err_tw;
    input tw_perr;
    input probe_err;
    input tw_par;
    input flush_done;
    input asi_done;
    input r_trap_w;
    input dc_tlb_tw;
    input sb_data_avail;
    input enbl_soft_tw;


begin
    next_tw_state = {30'b0};    /* set next_state to default. */
    case (1'b1)    // synopsys parallel_case full_case

/********* Reset *********************************************************/
    state == 30'b0:
            next_tw_state[IDLE] = 1'b1;

/********* IDLE state ****************************************************/
    state[IDLE]:

	    if (((strt_tw_for_m | flush_entry) & ~r_trap_w) |
		(dvma_ioflush))
		next_tw_state[PTE_FLUSH] = 1'b1;

            else if (tw_par & ~strt_tw_for_m & ~flush_done & 
			~(dc_tlb_tw & r_trap_w)) 
                next_tw_state[INIT_PAR] = 1'b1;

            else
                next_tw_state[IDLE] = 1'b1;

/********** INIT_PAR state - Load PAR with either CTPR,CXR or IBAR ******/
    state[INIT_PAR]:

            if (io_tlb_tw) 
                begin
                    next_tw_state[INIT_PAR_MEM] = 1'b1; /* IOROOT state */
                end
	    else if((~tlb_miss & virt_ptp2 & probe_lvl2) | 
		    (probe & enbl_soft_tw) |
		    (~tlb_miss & probe_entire))
		next_tw_state[PTE_TAG] = 1'b1;
	    else if(~tlb_miss & virt_ptp2 & ~probe)
		next_tw_state[VPTP_HIT] = 1'b1;
            else
                next_tw_state[ROOT] = 1'b1;

/********** ROOT state - CTPR look-up done during this state ************/
    state[ROOT]: 

            if (tlb_miss)
                begin
                    next_tw_state[RTMEM] = 1'b1; 
                end
            else if (probe_lvl0)
                next_tw_state[PTE_TAG] = 1'b1;
            else 
                next_tw_state[PTBL1] = 1'b1;   //lpar index1

/********** PTBL1 state - PTP/PTE level 1 lookup during this state ***/
     state[PTBL1]:

         if (dvma_req_x | sb_data_avail | (r_trap_w & dc_tlb_tw)) 
            begin
                next_tw_state[IDLE] = 1'b1; 
             end
         else if (tlb_miss & ~(dvma_req_x | sb_data_avail | 
		(r_trap_w & dc_tlb_tw))) 
            begin
                next_tw_state[PT1MEM] = 1'b1; 
             end
         else if (probe_lvl1)
             next_tw_state[PTE_TAG] = 1'b1;
         else 
             next_tw_state[PTBL2] = 1'b1;    //lpar index2

/********** PTBL2 state - PTP/PTE level 2 lookup during this state ***/
    state[PTBL2]:
        if (dvma_req_x | sb_data_avail | (r_trap_w & dc_tlb_tw))
            begin
                next_tw_state[IDLE] = 1'b1; 
            end
        else if (tlb_miss & ~(dvma_req_x | sb_data_avail | 
		(r_trap_w & dc_tlb_tw)))
            begin
                next_tw_state[PT2MEM] = 1'b1; 
            end
        else if (probe_lvl2)
            next_tw_state[PTE_TAG] = 1'b1;
        else 
            begin
                next_tw_state[PTBL3] = 1'b1; 
            end

/********** PTBL3 state - PTP/PTE level 3 lookup during this state ***/
    state[PTBL3]:
        if (dvma_req_x | sb_data_avail | (r_trap_w & dc_tlb_tw))
            begin   
                next_tw_state[IDLE] = 1'b1;
            end
        else if (~tlb_miss & probe_lvl3)
            next_tw_state[PTE_TAG] = 1'b1;
        else if (~(dvma_req_x | sb_data_avail | 
		(r_trap_w & dc_tlb_tw)))
            begin   
                next_tw_state[PT3MEM] = 1'b1;
            end
        else 
            begin
                next_tw_state[IDLE] = 1'b1;
            end
/********** PTBL2 state - PTP/PTE level 3 lookup during this state ***/
    state[VPTP_HIT]:
	next_tw_state[PTBL3] = 1'b1;

/********** RTMEM state - start memory access for root PTP look-up ***/
    state[RTMEM]:
        begin
            if (tdata_rdy) 
                begin
                    next_tw_state[RTWRT] = 1'b1;
                end
            else 
                begin
                    next_tw_state[RTMEM] = 1'b1;
                end
        end

/********** RTWRT state - finish memory access for root PTP look-up ***/
    state[RTWRT]:
        begin
            if (probe_lvl0 | (probe & ~(r_mdata_et == 2'b01)))
                next_tw_state[PTE_TAG] = 1'b1;
            else if (tw_perr) next_tw_state[ERR_XLT] = 1'b1;
            else
                case (r_mdata_et)                  //synopsys parallel_case
                    2'b01:  next_tw_state[PTBL1] = 1'b1;
                    2'b00:  next_tw_state[ERR_ADR] = 1'b1;
                    default:  next_tw_state[ERR_XLT] = 1'b1;
                endcase
            end

/********** PT1MEM state - start memory access for level 1 PTP look-up ***/
    state[PT1MEM]:
        begin
            if (tdata_rdy)
                next_tw_state[PT1WRT] = 1'b1;
            else
                next_tw_state[PT1MEM] = 1'b1;
        end

/********** PT1WRT state - finish memory access for level 1 PTP look-up ***/
    state[PT1WRT]:
        begin
			if (probe_entire & (r_mdata_et == 2'b10) & ~tw_perr)
				next_tw_state[PTE_TAG_U] = 1'b1;
            else if (probe_lvl1 | (probe & ~(r_mdata_et == 2'b01)))
                next_tw_state[PTE_TAG] = 1'b1;
            else if (tw_perr) next_tw_state[ERR_XLT] = 1'b1;
            else
                case (r_mdata_et)  // synopsys parallel_case full_case
                    2'b01:  next_tw_state[PTBL2] = 1'b1;
                    2'b10:  begin
                            case ({r_mdata_in_m, set_m_on_tw,
                                r_mdata_in_r}) // synopsys parallel_case
                                3'b000: next_tw_state[PTE_TAG_U] = 1'b1;
                                3'b001: next_tw_state[PTE_TAG] = 1'b1;
                                3'b010: next_tw_state[PTE_TAG_U] = 1'b1;
                                3'b011: next_tw_state[PTE_TAG_U] = 1'b1;
                                3'b101: next_tw_state[PTE_TAG] = 1'b1;
                                3'b111: next_tw_state[PTE_TAG] = 1'b1;
                                default: next_tw_state[ERR_ADR] = 1'b1;
                            endcase
                        end
                    2'b00: next_tw_state[ERR_ADR] = 1'b1;
                    2'b11: next_tw_state[ERR_XLT] = 1'b1;
                    endcase
                end

/********** PT2MEM state - start memory access for level 2 PTP look-up ***/
    state[PT2MEM]:
        begin
            if (tdata_rdy)
                next_tw_state[PT2WRT] = 1'b1;
            else 
                next_tw_state[PT2MEM] = 1'b1;
        end

/********** PT2WRT state - finish memory access for level 2 PTP look-up ***/
    state[PT2WRT]:
        begin
			if (probe_entire & (r_mdata_et == 2'b10) & ~tw_perr)
				next_tw_state[PTE_TAG_U] = 1'b1;
            else if (probe_lvl2 | (probe & ~(r_mdata_et == 2'b01)))
                next_tw_state[PTE_TAG] = 1'b1;
            else if (tw_perr) next_tw_state[ERR_XLT] = 1'b1;
            else
                case (r_mdata_et)  // synopsys parallel_case full_case
                    2'b01:  next_tw_state[PT3MEM] = 1'b1;
                    2'b10:  begin
                            case ({r_mdata_in_m, set_m_on_tw,
                                r_mdata_in_r}) // synopsys parallel_case
                                3'b000: next_tw_state[PTE_TAG_U] = 1'b1;
                                3'b001: next_tw_state[PTE_TAG] = 1'b1;
                                3'b010: next_tw_state[PTE_TAG_U] = 1'b1;
                                3'b011: next_tw_state[PTE_TAG_U] = 1'b1;
                                3'b101: next_tw_state[PTE_TAG] = 1'b1;
                                3'b111: next_tw_state[PTE_TAG] = 1'b1;
                                default: next_tw_state[ERR_ADR] = 1'b1;
                            endcase
                        end
                    2'b00: next_tw_state[ERR_ADR] = 1'b1;
                    2'b11: next_tw_state[ERR_XLT] = 1'b1;
                    endcase
                end

/********** PT3MEM state - start memory access for level 3 PTP look-up ***/
    state[PT3MEM]:
        begin
            if (tdata_rdy)
                next_tw_state[PT3WRT] = 1'b1;
            else 
                next_tw_state[PT3MEM] = 1'b1;
       end

/********** PT3WRT state - finish memory access for level 3 PTP look-up ***/
    state[PT3WRT]:
        begin
			if (probe_entire & (r_mdata_et == 2'b10) & ~tw_perr)
				next_tw_state[PTE_TAG_U] = 1'b1;
            else if (probe) next_tw_state[PRB_DONE] = 1'b1;
            else if (tw_perr) next_tw_state[ERR_XLT] = 1'b1;
            else
                case (r_mdata_et)  // synopsys parallel_case full_case
                    2'b10:  begin
                            case ({r_mdata_in_m, set_m_on_tw,
                                r_mdata_in_r}) // synopsys parallel_case
                                3'b000: next_tw_state[UPDATE] = 1'b1;
                                3'b001: next_tw_state[IDLE] = 1'b1;
                                3'b010: next_tw_state[UPDATE] = 1'b1;
                                3'b011: next_tw_state[UPDATE] = 1'b1;
                                3'b101: next_tw_state[IDLE] = 1'b1;
                                3'b111: next_tw_state[IDLE] = 1'b1;
                                default: next_tw_state[ERR_ADR] = 1'b1;
                            endcase
                        end
                    2'b00: next_tw_state[ERR_ADR] = 1'b1;
                    2'b01: next_tw_state[ERR_XLT] = 1'b1;
                    2'b11: next_tw_state[ERR_XLT] = 1'b1;
                    endcase
                end


/********** PTE_TAG state - Update TLB TAG with Virtual Addr. TAG ********/
    state[PTE_TAG]:
        if (probe)
            next_tw_state[PRB_DONE] = 1'b1;
        else
            next_tw_state[IDLE] = 1'b1;


/********** PTE_TAG_U state - Update TLB TAG with Virtual Addr. TAG ********/
    state[PTE_TAG_U]:
        next_tw_state[UPDATE] = 1'b1;


/********** IOROOT state - look-up with IBAR for IOPTE in memory ***********/ 
    state[INIT_PAR_MEM]:
        begin
            if (tdata_rdy)                    /* base for IOROOT and IOWRT */
                next_tw_state[INIT_PAR_WRT] = 1'b1;
            else 
                next_tw_state[INIT_PAR_MEM] = 1'b1;
        end

/********** IORWRT state - finish IOPTE read from memory ****************/
    state[INIT_PAR_WRT]:
        begin
            if (tw_perr) next_tw_state[ERR_XLT] = 1'b1;
            else
            begin
                case (r_mdata_et)  // synopsys parallel_case
                    2'b10:  next_tw_state[IDLE] = 1'b1;
                    default: next_tw_state[ERR_XLT] = 1'b1;
                endcase
            end
        end

/********** PTE_FLUSH state - FLUSH PTE entry ***************************/
    state[PTE_FLUSH]:
        if (r_flush_entry & ~flush_crs)
            next_tw_state[IDLE] = 1'b1;
	else if(r_flush_entry & flush_crs)
	    next_tw_state[PTE_FLUSH1] = 1'b1;
        else
            next_tw_state[INIT_PAR] = 1'b1;

/********** PTE_FLUSH1 state - flush all PTP after FLUSH CXT, REG, SEG **/
    state[PTE_FLUSH1]:
	if (virt_ptp2)
            next_tw_state[PTE_FLUSH2] = 1'b1;
        else
            next_tw_state[IDLE] = 1'b1;

/********** PTE_FLUSH2 state - flush all PTP after FLUSH CXT, REG, SEG **/
    state[PTE_FLUSH2]:
            next_tw_state[IDLE] = 1'b1;  

/********** UPDATE state - used to update R or M bit of PTE *************/
/********** Sets up a TLB read of PTE to be written to memory. **********/
    state[UPDATE]: next_tw_state[UPDATE_C] = 1'b1;

/********** UPDATE_C state - used to check permission of current access */
/**********   If protection/privilege error -> IDLE  (flush entry) ******/
    state[UPDATE_C]: 
        if (r_acc_err_tw)
            begin
            next_tw_state[UPDATE_F] = 1'b1;
            end
        else
            next_tw_state[UPDATE2] = 1'b1;

/********** UPDATE2 state - used to update R or M bit of PTE *************/
    state[UPDATE2]: 
        if (r_mmdaten & ~probe)
            next_tw_state[IDLE] = 1'b1;
        else if (r_mmdaten & probe)
            next_tw_state[PRB_DONE] = 1'b1;
        else
            next_tw_state[UPDATE2] = 1'b1;

/********** UPDATE_FLUSH state - used to flush PTEs that failed UPDATE_C ***/
    state[UPDATE_F]:
        next_tw_state[IDLE] = 1'b1;

/********** ERR_XLT state - used to indicate a translation error **********/
/**********  Go to PTE_TAG to invalidate entry (writes 0 in valid bit) ****/
    state[ERR_XLT]:  next_tw_state[PTE_TAG] = 1'b1;

/********** ERR_ADR state - used to indicate an invalid address error *****/
/**********  Go to PTE_TAG to invalidate entry (writes 0 in valid bit) ****/
    state[ERR_ADR]:  next_tw_state[PTE_TAG] = 1'b1;

/********** PRB_DONE state - used to indicate the end of a Probe op   *****/
    state[PRB_DONE]:
        if (~asi_done)
            next_tw_state[PRB_DONE] = 1'b1;
        else if (probe_entire & ~probe_err)
            next_tw_state[IDLE] = 1'b1;
        else
            next_tw_state[PRB_CLR] = 1'b1;

/********** PRB_CLR state - used to indicate the end of a Probe op   *****/
    state[PRB_CLR]: next_tw_state[IDLE] = 1'b1;

    endcase    // endcase for case(state)
    end
endfunction

     
    wire [29:0] state_in = next_tw_state(state, io_tlb_tw, 
                        tlb_miss, dvma_req_x,
                        r_dc_tlb, st_miss_x, virt_ptp2,
                        tdata_rdy, r_mdata_et, flush_crs,
                        r_mdata_in_r, r_mdata_in_m, 
                        flush_entry, dvma_ioflush, r_flush_entry,
                        probe, probe_entire, probe_lvl0,
                        probe_lvl1, probe_lvl2, probe_lvl3,
                        set_m_on_tw,
                        strt_tw_for_m, r_mmdaten, r_acc_err_tw,
			tw_perr, probe_err,tw_par, flush_done, 
			asi_done, 
			r_trap_w, dc_tlb_tw, sb_data_avail,enbl_soft_tw);

/*** State regsiter bits ****************************************************/

    Mflipflop_r_30 mtwsm_30(state,state_in,~ss_reset,ss_clock) ;

/*** Table Walk done ********************************************************/
/***  must ensure decode of state that return to IDLE                     ***/
/***  this is for normal tablewalks only (not probes or flushes)          ***/

    assign tw_done = (~probe & (state[UPDATE_F] | state[PTE_TAG] |
	  (state[UPDATE2] & r_mmdaten) |
	  (state[PT3WRT] & (r_mdata_et == 2'b10) & ~tw_perr &
	    ((~r_mdata_in_m & ~set_m_on_tw & r_mdata_in_r) |
	    (r_mdata_in_m & ~set_m_on_tw & r_mdata_in_r) |
	    (r_mdata_in_m & set_m_on_tw & r_mdata_in_r))))) |
	  ((state[PTBL1] | state[PTBL2] | state[PTBL3]) & 
		(dvma_req_x | sb_data_avail | (r_trap_w & dc_tlb_tw))) |
	  (state[INIT_PAR_WRT] & (r_mdata_et == 2'b10)) |
	  (dc_tlb_tw & r_trap_w & state[IDLE]) ;        // for fast traps

    wire tw_abort_in =  (state[PTBL1] | state[PTBL2] | state[PTBL3]) & 
			(dvma_req_x | sb_data_avail | (r_trap_w & dc_tlb_tw));
    wire tw_abort;
    Mflipflop_r_1 tw_abort_ff_1(tw_abort,tw_abort_in,~ss_reset,ss_clock) ;

/*** TLB RAM write enable ***************************************************/

    assign ldtlb_data_tw = (((state[RTMEM])| /* RTMEM state */
                            (state[PT1MEM]) |  /* PTBL1 state */
                            (state[PT2MEM]) |  /* PTBL2 state */
                            (state[PT3MEM]) |  /* PTBL3 state */
                            (state[INIT_PAR_MEM])) & /* IOROOT */
                            tdata_rdy) ;
							

/*** TLB CAM write enable ***************************************************/

    assign ldtlb_tag_tw = (ldtlb_data_tw |
			(state[PT3WRT] & tw_prb_err) |
                        (state[RTWRT] &
                        ((probe & ~(r_mdata_et == 2'b01)))) |
                        ((state[PT1WRT]) &
                        ((probe & ~(r_mdata_et == 2'b01)))) |
                        ((state[PT2WRT]) &
                        ((probe & ~(r_mdata_et == 2'b01)))) |
                        (((state[RTWRT]) |
                          (state[PT1WRT]) |
                          (state[PT2WRT])) &
                          ~(r_mdata_et == 2'b01)));

/****************************************************************************/
/***** va_sel_par_in is basically the same as the table_walk signal     ****/
/*****  except that it's disabled during PTE tag writes (must load       ****/
/*****  virtual address as PTE tag).                                     ****/
/*****  FIX for P0 TLB flush cxt/reg/seg multiple cam match bug          ****/
/*****    No va_sel_par_in during any of the PTE_FLUSH states            ****/

    assign va_sel_par_in = ~((flush_tlb_ctx | flush_tlb_seg | flush_tlb_reg | 
				flush_tlb_pte | flush_tlb_all) & dc_tlb_tw) &
			    (~state[IDLE] & ~state[VPTP_HIT] &
                            ~state[ERR_ADR] & ~state[ERR_XLT] &
                            ~(state[PT3WRT] | state[INIT_PAR_WRT] |
                              state[UPDATE_C] | state[UPDATE2] | 
                              state[PTE_TAG] | state[PTE_TAG_U] |
                              (state[PTE_FLUSH] & ((virt_ptp2 & ~r_flush_entry) |
				(r_flush_entry & ~flush_crs))) |
				state[PRB_DONE] | state[PRB_CLR]) &
                            ~(state[PT3MEM] | state[INIT_PAR_MEM] |
                               ((state[RTWRT] &
                                (probe_lvl0 | ~(r_mdata_et == 2'b01))) |
                                (state[PT1WRT] &
                                (probe_lvl1 | ~(r_mdata_et == 2'b01))) |
                                (state[PT2WRT] &
                                (probe_lvl2 | ~(r_mdata_et == 2'b01)))
                                )) &
			    ~(state[PTBL3] | state[PTBL2]) &
			    ~((state[PTBL1] | state[PT1WRT] | state[PT2MEM]) &
				 virt_ptp2)) ;

/*** Load PAR decode - table walk decode for load PAR.  ********************/

    assign ld_par_tw = ((state[INIT_PAR]) | state[VPTP_HIT] |
                        (((state[ROOT] & ~(probe_lvl0 & ~tlb_miss)) |
                          (state[PTBL1] & ~(probe_lvl1 & ~tlb_miss)) |
                          (state[PTBL3] & ~(probe_lvl3 & ~tlb_miss)) |
                          (state[PTBL2] & ~(probe_lvl2 & ~tlb_miss))) &
                          ~tlb_miss) |
                        ((state[RTWRT] | state[PT1WRT] | state[PT2WRT]) &
                         (r_mdata_et == 2'b01)));

/****************************************************************************/
/*** Read word request (1 cycle early) for marb_sm.                       ***/

    assign read_word_mreq = (state[INIT_PAR] |
                         state[ROOT] |
                         state[PTBL1] |
                         state[PTBL2] |
                         state[PTBL3]);

/****************************************************************************/
/*** Load memory request reg. decode                                      ***/

    assign ld_mreq_tw = read_word_mreq | tw_write_req ;

/****************************************************************************/
/*** Read word request (current cycle).                                   ***/
    assign tw_read_req = ((state[INIT_PAR_MEM]) |
                        (state[RTMEM]) |
                        (state[PT1MEM]) |
                        (state[PT2MEM]) |
                        (state[PT3MEM])) ;

/****************************************************************************/
/***** tw_write_req is used for writing a PTE to memory.  This is done    ***/
/*****  only in the UPDATE state, and is used to slect the PTE onto the   ***/
/*****  mc_mdata bus.  It must be de-asserted 1-cycle before IDLE, since  ***/
/*****  the TLB inputs are registerd and require 1-cycle latency.         ***/

    assign tw_write_req = (state[UPDATE2] & ~ss_reset);

/****************************************************************************/
/*** TLB input IO - IO flag for TLB CAM input.                          ***/

    assign tw_io_bit = ((state[VPTP_HIT] | state[IDLE]) & tw_par & 
			~flush_entry & ~io_tlb_tw & virt_ptp2 & 
			~probe_entire & ~strt_tw_for_m) |
                     (state[PTBL1] & virt_ptp2) | 
                     (state[IDLE] & (flush_iopte | flush_ioall)) | 
                     (state[PTE_FLUSH] & tw_par & virt_ptp2 & ~r_flush_entry) |
		     (state[PTE_FLUSH1] & virt_ptp2) |
                     (state[PT1WRT] & virt_ptp2 & (r_mdata_et == 2'b01)) |
                     (state[PT2MEM] &  virt_ptp2);
/****************************************************************************/
/*** TLB input PTP - PTP flag for TLB CAM input.                          ***/
/***  Also used for Context select for loading the TLB tag.               ***/

    assign ptp_in = (state[ROOT] |
                     state[PTBL1] |
//                     state[PTBL2] |
                     (state[PTE_FLUSH] & tw_par & 
			(flush_crs | (virt_ptp2 & ~r_flush_entry))) |
                     (state[PTE_FLUSH1] & virt_ptp2) |
                     state[INIT_PAR]  | state[VPTP_HIT] |
                     (state[RTMEM] | state[PT1MEM] | state[PT2MEM]) |
                     ((state[RTWRT] | state[PT1WRT] | state[PT2WRT]) &
                      (r_mdata_et == 2'b01)) | 
                     (state[PRB_DONE] & r_ptp_flush) |
                     (state[IDLE] & tw_par & virt_ptp2 & ~probe_entire & 
			~(dvma_ioflush | flush_entry | strt_tw_for_m))  |
		     (state[PTBL3] & tw_par & virt_ptp2 & ~probe_entire));

/****************************************************************************/
/*** TLB superviosr bit input                                             ***/

assign io_s_bit =  flush_iopte | flush_ioall ;
assign va_s_in = (tw_sin & tw_tlb_nxt) | io_s_bit |
			(state[PTE_FLUSH1] & virt_ptp2) ;


/****************************************************************************/
/*** Store state that a probe encountered a PTP at last level.            ***/
/*** Needed for flush ***/

    assign ptp_flush_in = ((state[RTWRT] & probe_lvl0) |
                           (state[PT1WRT] & probe_lvl1) |
                           (state[PT2WRT] & probe_lvl2)) &
                           (r_mdata_et == 2'b01) ;

/****************************************************************************/
/*** TLB data input level bits - Level bits that are input to TLB RAM     ***/
/*** Decode for raw TLB level bits from tag (software tag[12:10])         ***/
/***                                                                      ***/
/***    cam_lvl[2:0]	tlb_lvl_dcd[1:0] (PTE level)                      ***/
/***    ------------    ---------------- -----------                      ***/
/***       000                00           level-0                        ***/
/***       100                01           level-1                        ***/
/***       110                10           level-2                        ***/
/***       111                11           level-3                        ***/
/***       111                11           IO-PTE                         ***/


    assign tlb_ram_lvl[2] = state[PT1MEM] | state[PT1WRT] |
			    state[PT2MEM] | state[PT2WRT] |
			    state[PT3MEM] | state[PT3WRT] | state[VPTP_HIT] |
			    state[INIT_PAR_MEM] | state[INIT_PAR_WRT] ;

    assign tlb_ram_lvl[1] = state[PT2MEM] | state[PT2WRT] |
			    state[PT3MEM] | state[PT3WRT] | state[VPTP_HIT] |
			    state[INIT_PAR_MEM] | state[INIT_PAR_WRT] ;

    assign tlb_ram_lvl[0] = state[PT3MEM] | state[PT3WRT] | 
			    state[INIT_PAR_MEM] | state[INIT_PAR_WRT] ;

Next12
HierarchyFilesModulesSignalsTasksFunctionsHelp

This page: Created:Thu Aug 19 11:59:36 1999
From: ../../../sparc_v8/ssparc/mmu/m_mmu_cntl/rtl/rl_tw_sm.v

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