/******************************************************************************/
/* */
/* 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_par_cntl.v
***
****************************************************************************
****************************************************************************/
//****************************************************************************
//
// @(#)rl_par_cntl.v 1.164 9/3/93
// rl_par_cntl.v
//
// Description:
// PAR Controller
//
// Dependencies: Yup....
//
//****************************************************************************
/* functional model of MMU PAR Controller */
module rl_par_cntl
(
par_sel,
req_pending,
tlb_acc_cmp,
tlb_mbit_cmp,
mbit_sel,
va_mux0_sel,
va_mux1_sel,
va_mux_sel,
ic_tlb,
ic_tlb_state,
ic_tlb_tw,
r_ic_par,
dc_tlb,
dc_tlb_state,
dc_tlb_tw,
wr_tlb_tw,
io_tlb,
io_tlb_tw,
wr_tlb,
r_dc_par,
r_sb_par,
sb_par,
tw_par,
r_tw_par,
mmu_asi_op,
hold_par,
ld_par,
io_tlb_nxt,
data_op,
ic_in_par,
dc_in_par,
ic_par_state,
dc_par_state,
ipar_valid,
dpar_valid,
sr_tw,
r_pipe_moved,
mm_mem_dbg,
r_mbsy,
r_mem_space,
mm_dabort,
mm_iabort,
tlb_miss,
tlb_hit,
tlb_err,
tlb_m_miss,
probe_done,
flush_done,
r_flush_entry,
asi_dcd3,
asi_dcd3_w,
probe_in,
flush_in,
mem_issue_req,
ic_idle,
st_op_w,
last_st_w,
ldsto_w,
read_w,
ic_miss,
ic_miss_sustain,
dc_miss,
dc_miss_sustain,
ldst_st,
ldst_block,
mbsy,
tw_abort,
tw_done,
wb_valid_t,
wb_valid_x,
ld_op_e,
st_op_e,
dvma_req_s,
dvma_req_x,
sbc_pa_valid,
r_cntl_space,
mmasi,
asi_done,
normal_asi_w,
va_sel_par_in,
iu_pipe_hold,
ic_issue_req,
dc_issue_req,
ld_par_tw,
cam_reg_hld,
data_acc_s,
r_srd_ioreq,
sb_par_clr, /* signal IO control space op is done */
r_trap_w,
pipe_moved,
dcc_idle,
wb_empty,
mreq_st, /* mm_mreq[3] is asserted */
ldtlb_tag_tw,
ic_stream,
dc_stream,
r_dc_miss,
flush_iopte,
tw_read_req,
enbl_soft_tw,
st_miss_x,
io_tlb_err,
mm_dstat_avail,
mm_cache_stat,
ss_clock,
ss_scan_mode,
ss_reset);
output[1:0] par_sel
; // PAR mux select
output req_pending
; // PAR has a request pending
output[5:0] tlb_acc_cmp
; // mbit decode for ACC (protection) compares
output tlb_mbit_cmp
; // mbit decode for compares
output[2:0] mbit_sel
; // mbit mux selects
output[3:0] va_mux0_sel
; // va mux selects
output[4:0] va_mux1_sel
; // va mux selects
output[3:0] va_mux_sel
;
output ic_tlb
; // par cntl in ic_tlb state qualified w/ ~bad_xlate
output ic_tlb_state
; // par cntl in ic_tlb state
output ic_tlb_tw
; // par cntl in ic_tlb_tw state
output r_ic_par
; // par cntl was in ic_tlb or ic_par state last cycle
output dc_tlb
; // par cntl in dc_tlb state qualified w/ ~bad_xlate
output dc_tlb_state
; // par cntl in dc_tlb state
output dc_tlb_tw
; // par cntl in dc_tlb_tw state
output wr_tlb_tw
; // par cntl in wr_tlb_tw state
output io_tlb
; // par cntl in io_tlb state
output io_tlb_tw
; // par cntl in io_tlb_tw state
output wr_tlb
; // par cntl in wr_tlb state
output r_dc_par
; // par cntl was in dc_tlb or dc_par state last cycle
output r_sb_par
; // par cntl was in io_tlb state last cycle
output sb_par
; // par cntl was in io_tlb state last cycle
output tw_par
; // par cntl was in a tablewalk state last cycle
output r_tw_par
; // par cntl was in a tablewalk state last cycle
output mmu_asi_op
; // ASI operation pending in the MMU.
output hold_par
; // hold for PAR
output ld_par
; // Load for PAR
output io_tlb_nxt
; // I/O translation next cycle
output data_op
; // D-cache translation in current cycle
output ic_in_par
; // I-cache address in PAR
output dc_in_par
; // D-cache address in PAR
output ic_par_state
; // I-cache address in PAR and waiting for mop
output dc_par_state
; // D-cache address in PAR and waiting for mop
output ipar_valid
; // ipar register is valid (hold it)
output dpar_valid
; // dpar register is valid (hold it)
output sr_tw
; // SRMMU tablewalk in progress
output r_pipe_moved
; //
output [1:0] mm_mem_dbg
; // Memory access debug signals
input r_mbsy
;
input r_mem_space
;
input mm_dabort
; // input mmabort signal
input mm_iabort
; // input mmabort signal
input probe_done
; // probe op done
input flush_done
; // flush op done
input r_flush_entry
; // cycle after TLB lookup (compare)
input asi_dcd3
; // ASI decode = 0x03 in W-stage
input asi_dcd3_w
; // ASI decode = 0x03 in W-stage (non-qualified)
input probe_in
; // ld ASI decode = 0x03 in W-stage (non-qualified)
input flush_in
; // st ASI decode = 0x03 in W-stage (non-qualified)
input tlb_miss
; // tlb miss this cycle
input tlb_hit
; // tlb hit this cycle
input tlb_err
; // tlb err this cycle
input tlb_m_miss
; // tlb Mbit miss this cycle
input ic_idle
; // ic in idle state
input mem_issue_req
; // indicates that a memory request is being issued
input st_op_w
; // store in W stage
input last_st_w
; // last store miss in W stage
input ldsto_w
; // load/store miss in W stage
input read_w
; // read in W stage
input ic_miss
; // I$ tag miss *** Late signal ***
input ic_miss_sustain
; // I$ tag miss sustain
input dc_miss
; // D$ tag miss *** Late signal ***
input dc_miss_sustain
; // D$ tag miss sustain
input ldst_st
; // store part of ldsto
input ldst_block
; // store part of ldsto
input mbsy
; // Memory busy signal
input tw_done
; // Table Walk done signal from tw_sm
input tw_abort
; // Table Walk abort signal from tw_sm
input wb_valid_t
; // Write Buffer valid signal (translate stage)
input wb_valid_x
; // Write Buffer valid signal (execute stage)
input ld_op_e
; // Load operation in e-stage
input st_op_e
; // Store operation in e-stage
input dvma_req_s
; // from mmu_lgc - valid sb_ioreq pending
input dvma_req_x
; // from mmu_lgc - valid sb_ioreq pending
input sbc_pa_valid
; // from MMU - valid PAR for last sb_ioreq
input r_cntl_space
; // control space operation has been decoded.
input mmasi
;
input asi_done
;
input normal_asi_w
;
input va_sel_par_in
;
input iu_pipe_hold
;
input ic_issue_req
;
input dc_issue_req
;
input ld_par_tw
;
input cam_reg_hld
;
input[2:0] data_acc_s
;
input r_srd_ioreq
;
input sb_par_clr
; // signal IO control space op is done
input r_trap_w
;
input pipe_moved
;
input dcc_idle
;
input wb_empty
;
input mreq_st
;
input ldtlb_tag_tw
;
input ic_stream
;
input dc_stream
;
input r_dc_miss
;
input flush_iopte
;
input tw_read_req
;
input enbl_soft_tw
;
input st_miss_x
;
input io_tlb_err
;
input mm_dstat_avail
;
input mm_cache_stat
;
input ss_clock
; // input clock
input ss_scan_mode
; // input scan_mode
input ss_reset
; // input reset
// state names
parameter DC_TLB = 0,
DC_TLB_TW = 1,
DC_PAR = 2,
IC_TLB = 3,
IC_TLB_TW = 4,
IC_PAR = 5,
IO_TLB = 6,
IO_TLB_TW = 7,
WR_TLB = 8,
WR_TLB_TW = 9,
ASI_OP = 10;
// 9876543210
parameter [10:0] D_DC_TLB = 11'b00000000001,
D_DC_TLB_TW = 11'b00000000010,
D_DC_PAR = 11'b00000000100,
D_IC_TLB = 11'b00000001000,
D_IC_TLB_TW = 11'b00000010000,
D_IC_PAR = 11'b00000100000,
D_IO_TLB = 11'b00001000000,
D_IO_TLB_TW = 11'b00010000000,
D_WR_TLB = 11'b00100000000,
D_WR_TLB_TW = 11'b01000000000,
D_ASI_OP = 11'b10000000000;
wire [10:0] state
;
/*** Display routine for tw sm state information. *****************/
// synopsys translate_off
reg[31*8:1] par_state_name
;
reg[31*8:1] va_mux_name
;
always @ state
case (state)
D_DC_TLB: par_state_name = "[dc_tlb] - dc tlb idle";
D_DC_TLB_TW: par_state_name = "[dc_tlb_tw] - dc table walk";
D_DC_PAR: par_state_name = "[dc_par] - dc par valid";
D_IC_TLB: par_state_name = "[ic_tlb] - ic tlb idle";
D_IC_TLB_TW: par_state_name = "[ic_tlb_tw] - ic table walk";
D_IC_PAR: par_state_name = "[ic_par] - ic par valid";
D_IO_TLB: par_state_name = "[io_tlb] - io tlb lookup";
D_IO_TLB_TW: par_state_name = "[io_tlb_tw] - io table walk";
D_WR_TLB: par_state_name = "[wr_tlb] - wr buf tlb lookup";
D_WR_TLB_TW: par_state_name = "[wr_tlb_tw] - wr buf table walk";
D_ASI_OP: par_state_name = "[asi_op] - ASI op in progress";
default: par_state_name = "[**bad_news**] - default";
endcase
always @ (va_mux0_sel | va_mux1_sel)
case (va_mux1_sel)
5'b00001: begin
case(va_mux0_sel)
4'b0001: va_mux_name = "r_i_vaddr[31:12]";
4'b0010: va_mux_name = "r_d_vaddr[31:12]";
4'b0100: va_mux_name = "misc_in[31:12]";
4'b1000: va_mux_name = "wr_buf_3_out[31:12]";
default: va_mux_name = "[**bad_news**] - default";
endcase
end
5'b00010: va_mux_name = "data_pa[27:08]";
5'b00100: va_mux_name = "i_vaddr[31:12]";
5'b01000: va_mux_name = "d_vaddr[31:12]";
5'b10000: va_mux_name = "io_addr[31:12]";
default: va_mux_name = "[**bad_news**] - default";
endcase
// synopsys translate_on
/***************************************************************************/
/*** wire definitions ******************************************************/
wire sel_rdva
; /* Select Reg'd DVA **/
wire sel_riva
; /* Select Reg'd IVA **/
wire wr_tlb ; /* write buffer translation in progress */
wire bad_xlate
; /* bad translation in progress */
wire dc_mop_e
= ld_op_e | st_op_e ; /* D$ operation in E-stage */
wire dtag_chk_done
;
wire itag_chk_done
;
wire set_dpar
;
wire dc_mop_w
;
MflipflopR_1 dc_mop_w_ff_1(dc_mop_w,dc_mop_e,ss_clock,iu_pipe_hold,ss_reset) ;
wire dpar_valid ; /* need to make valid bit here */
wire ipar_valid ; /* need to make valid bit here */
wire dc_alloc_pnd
; /* need to make valid bit here */
/***************************************************************************/
function [10:0] next_par_state;
input[10:0] state;
input wb_valid_x;
input dc_alloc_pnd;
input ldst_block;
input dvma_req_s;
input sbc_pa_valid;
input sb_par_clr;
input r_srd_ioreq;
input wb_valid_t;
input dpar_valid;
input ipar_valid;
input dc_miss;
input dc_miss_sustain;
input ic_miss;
input ic_miss_sustain;
input ic_issue_req;
input dc_issue_req;
input tw_done;
input mbsy;
input tlb_hit;
input tlb_err;
input tlb_miss;
input tlb_m_miss;
input st_miss_x;
input r_cntl_space;
input dc_mop_e;
input dc_mop_w;
input mem_issue_req;
input mmasi;
input asi_done;
input normal_asi_w;
input last_st_w;
input probe_done;
input flush_done;
input asi_dcd3;
input r_mem_space;
input r_mbsy;
input r_ic_par;
input r_sb_par;
input r_trap_w;
input mm_iabort;
input mm_dabort;
input pipe_moved;
input bad_xlate;
input dtag_chk_done;
input dcc_idle;
input ic_stream;
input set_dpar;
input io_tlb_err;
input enbl_soft_tw;
begin
next_par_state = {11'b0}; /* set next_state to default. */
case (1'b1) // synopsys parallel_case full_case
/********* Reset ***********************************************************/
state == 11'b0:
next_par_state[IC_TLB] = 1'b1;
/********* DC_TLB state ****************************************************/
state[DC_TLB]:
case(1'b1) // synopsys full_case parallel_case
/** SBC request ********************************************/
/** highest priority - go do it. *************************/
(dvma_req_s):
next_par_state[IO_TLB] = 1'b1;
/** ASI operation ******************************************/
(mmasi & ~dvma_req_s) :
next_par_state[ASI_OP] = 1'b1;
/** Data PAR valid (and waiting) ***************************/
/** Could be setting dpar this cycle or already set *****/
/** 1. pipe moving and a D$ miss & TLB hit *****/
/** 2. pipe held and a D$ miss & TLB hit *****/
(set_dpar & ~dvma_req_s) |
(dpar_valid & ~dvma_req_s):
next_par_state[DC_PAR] = 1'b1;
/** Write Buffer Valid - DPAR empty ************************/
(wb_valid_t & ~(last_st_w & (dc_miss | ~dcc_idle)) &
~dpar_valid & ~dvma_req_s & ~mmasi):
next_par_state[WR_TLB] = 1'b1;
/** D-cache miss and TLB miss (need tablewalk) *************/
(dc_miss & (asi_dcd3 |
(tlb_m_miss & ~tlb_err & ~enbl_soft_tw)) &
~dpar_valid & normal_asi_w & pipe_moved & ~bad_xlate &
(~wb_valid_t | last_st_w) & ~dvma_req_s & ~mmasi) |
(dc_miss_sustain & (asi_dcd3 |
(tlb_m_miss & ~tlb_err & ~enbl_soft_tw)) &
~dpar_valid & normal_asi_w & ~pipe_moved & ~bad_xlate &
(~wb_valid_t | last_st_w) & ~dvma_req_s & ~mmasi) :
next_par_state[DC_TLB_TW] = 1'b1;
/** I-par valid pending ************************************/
(ipar_valid & ~dc_miss_sustain & ~dpar_valid &
~wb_valid_t & ~dvma_req_s & ~mmasi) :
next_par_state[IC_PAR] = 1'b1;
/** I-cache miss *******************************************/
(((ic_miss_sustain & ~pipe_moved) | ~(dc_mop_e | dc_mop_w)) &
~dc_miss_sustain & ~dpar_valid & ~ipar_valid & ~wb_valid_t &
~dvma_req_s & ~mmasi) :
next_par_state[IC_TLB] = 1'b1;
/** Default case ********************************************/
/** -> IC_TLB transition ***/
/** -> ~DC_PAR/DC_TLB_TW transition ***/
/** -> WR_TLB transition ***/
/** -> DC_PAR transition ***/
/** -> IC_PAR transition ***/
/** -> IO_TLB transition ***/
/** -> ASI_OP transition ***/
default:
next_par_state[DC_TLB] = 1'b1;
endcase
/********* DC_PAR state ****************************************************/
/********* DPAR is valid - exit for handling DVMA request *****/
/********* - exit for issue_req for D$ op pending *****/
/********* - exit for traps that clear DPAR *****/
state[DC_PAR]:
if
((dvma_req_s & ~ldst_block) | dc_issue_req |
(r_trap_w & ~(wb_valid_x | dc_alloc_pnd )))
next_par_state[DC_TLB] = 1'b1;
else
next_par_state[DC_PAR] = 1'b1;
/********* DC_TLB_TW state *************************************************/
state[DC_TLB_TW]:
case(1'b1) // synopsys full_case parallel_case
/** normal case ******************************************/
(tw_done):
next_par_state[DC_TLB] = 1'b1;
/** normal case ******************************************/
(probe_done | flush_done):
next_par_state[ASI_OP] = 1'b1;
/** normal case ******************************************/
(~(tw_done | probe_done | flush_done)):
next_par_state[DC_TLB_TW] = 1'b1;
endcase
/********* IC_TLB state ****************************************************/
state[IC_TLB]:
case(1'b1) // synopsys full_case parallel_case
/** SBC request ********************************************/
(dvma_req_s):
next_par_state[IO_TLB] = 1'b1;
/** D-cache miss pending ***********************************/
((dc_miss_sustain | wb_valid_x |
(dc_mop_e & (pipe_moved | ~ic_miss_sustain))) & ~dvma_req_s):
next_par_state[DC_TLB] = 1'b1;
/** I-PAR valid ********************************************/
/** I-cache miss w/ TLB hit ********************************/
/** use tlb_miss since I$ translate must complete *********/
(((ipar_valid & ~ic_issue_req & ~(dc_miss_sustain | wb_valid_x)) |
(ic_miss & tlb_hit & ~bad_xlate &
~(dc_miss_sustain | wb_valid_x | (dc_mop_e &
(pipe_moved | ~ic_miss_sustain))))) & ~dvma_req_s):
next_par_state[IC_PAR] = 1'b1;
/** I-cache miss w/ TLB miss *******************************/
(ic_miss & tlb_miss & ~bad_xlate & ~mm_iabort & ~enbl_soft_tw &
~(dc_miss_sustain | wb_valid_x | (dc_mop_e &
(pipe_moved | ~ic_miss_sustain))) & ~dvma_req_s):
next_par_state[IC_TLB_TW] = 1'b1;
/** Default ************************************************/
/** NOT of all the above cases *****************************/
(~((dvma_req_s) |
((dc_miss_sustain | wb_valid_x |
(dc_mop_e & (pipe_moved | ~ic_miss_sustain))) & ~dvma_req_s) |
(((ipar_valid & ~ic_issue_req & ~(dc_miss_sustain | wb_valid_x)) |
(ic_miss & tlb_hit & ~bad_xlate &
~(dc_miss_sustain | wb_valid_x | (dc_mop_e &
(pipe_moved | ~ic_miss_sustain))))) & ~dvma_req_s) |
(ic_miss & tlb_miss & ~bad_xlate & ~mm_iabort & ~enbl_soft_tw &
~(dc_miss_sustain | wb_valid_x | (dc_mop_e &
(pipe_moved | ~ic_miss_sustain))) & ~dvma_req_s))):
next_par_state[IC_TLB] = 1'b1;
endcase
/********* IC_PAR state ****************************************************/
/********* IPAR is valid - exit for handling DVMA request *****/
/********* - exit for D$ miss pending *****/
/********* - exit for issue_req for I$ op pending *****/
state[IC_PAR]:
if (dvma_req_s | dc_miss_sustain | ic_issue_req)
next_par_state[IC_TLB] = 1'b1;
else
next_par_state[IC_PAR] = 1'b1;
/********* IC_TLB_TW state *************************************************/
state[IC_TLB_TW]:
if (tw_done | mm_iabort)
next_par_state[IC_TLB] = 1'b1;
else
next_par_state[IC_TLB_TW] = 1'b1;
/********* IO_TLB state ****************************************************/
/*** 'sbc_pa_valid' asserted for each DMA op requested, AND sxlate ********/
/*** Could add special case for (sxlate & tlb_hit) to branch out ********/
/*** of IO_TLB - would save a cycle. ********/
state[IO_TLB]:
case(1'b1) // synopsys full_case parallel_case
/** IO translation missed TLB ******************************/
(dvma_req_s & tlb_miss & ~io_tlb_err):
next_par_state[IO_TLB_TW] = 1'b1;
/** Wait for DMA op to be started **************************/
/** Clear on pa_valid (except for control space ops) ******/
/** Clear on sb_par_clr - from control space op finish ****/
/** Clear on issue_req (ensure it was from io_op ****/
(dvma_req_s & ~(sbc_pa_valid & ~(r_cntl_space & r_srd_ioreq)) &
~sb_par_clr & ~tlb_miss & ~io_tlb_err &
~(mem_issue_req & r_sb_par)) :
next_par_state[IO_TLB] = 1'b1;
/** Data PAR valid (and waiting) ***************************/
(dpar_valid & ((sbc_pa_valid & ~(r_cntl_space & r_srd_ioreq)) |
sb_par_clr | (mem_issue_req & r_sb_par) |
io_tlb_err | ~dvma_req_s)) :
next_par_state[DC_PAR] = 1'b1;
/** Instruction PAR valid (and waiting) ********************/
(ipar_valid & ~dpar_valid &
((sbc_pa_valid & ~(r_cntl_space & r_srd_ioreq)) |
sb_par_clr | (mem_issue_req & r_sb_par) |
io_tlb_err | ~dvma_req_s)):
next_par_state[IC_PAR] = 1'b1;
/** Default ************************************************/
(~ipar_valid & ~dpar_valid &
((sbc_pa_valid & ~(r_cntl_space & r_srd_ioreq)) |
sb_par_clr | mem_issue_req | io_tlb_err | ~dvma_req_s)):
next_par_state[DC_TLB] = 1'b1;
endcase
/********* IO_TLB_TW state *************************************************/
state[IO_TLB_TW]:
if (tw_done)
next_par_state[IO_TLB] = 1'b1;
else
next_par_state[IO_TLB_TW] = 1'b1;
/********* WR_TLB state ****************************************************/
state[WR_TLB]:
case(1'b1) // synopsys full_case parallel_case
/** Write buffer translation missed TLB ***************************/
/** TLB miss or Mbit =0 *****/
(tlb_m_miss & ~dvma_req_s & ~mm_dabort & ~bad_xlate &
wb_valid_x & ~st_miss_x):
next_par_state[WR_TLB_TW] = 1'b1;
/** Write buffer translation hit **********************************/
/** TLB hit no error *****/
(tlb_hit & ~dvma_req_s & ~mm_dabort & ~bad_xlate &
wb_valid_x & ~st_miss_x):
next_par_state[DC_PAR] = 1'b1;
/** Write buffer translation hit TLB with error *******************/
/** Access error *****/
(((~tlb_hit & ~tlb_m_miss) | bad_xlate) &
~dvma_req_s & ~mm_dabort & wb_valid_x & ~st_miss_x):
next_par_state[WR_TLB] = 1'b1;
/** Write buffer translation hit TLB with error *******************/
/** Write aborted or DVMA req pending or Write cancelled *****/
(mm_dabort | dvma_req_s | ~wb_valid_x | st_miss_x):
next_par_state[DC_TLB] = 1'b1;
endcase
/********* WR_TLB_TW state *************************************************/
state[WR_TLB_TW]:
if (tw_done)
next_par_state[WR_TLB] = 1'b1;
else
next_par_state[WR_TLB_TW] = 1'b1;
/********* ASI_OP state ****************************************************/
state[ASI_OP]:
if (asi_done | mm_dabort | r_trap_w)
next_par_state[DC_TLB] = 1'b1;
else
next_par_state[ASI_OP] = 1'b1;
endcase // endcase for case(state)
end
endfunction
wire [10:0] state_in
= next_par_state(state, wb_valid_x, dc_alloc_pnd, ldst_block,
dvma_req_s, sbc_pa_valid, sb_par_clr, r_srd_ioreq,
wb_valid_t, dpar_valid, ipar_valid,
dc_miss, dc_miss_sustain, ic_miss, ic_miss_sustain,
ic_issue_req, dc_issue_req,
tw_done, mbsy, tlb_hit, tlb_err, tlb_miss,
tlb_m_miss, st_miss_x, r_cntl_space,
dc_mop_e, dc_mop_w, mem_issue_req,
mmasi, asi_done, normal_asi_w, last_st_w,
probe_done, flush_done, asi_dcd3,
r_mem_space, r_mbsy, r_ic_par, r_sb_par,
r_trap_w, mm_iabort, mm_dabort,
pipe_moved, bad_xlate, dtag_chk_done,
dcc_idle, ic_stream, set_dpar, io_tlb_err, enbl_soft_tw );
/*** State register bits ***************************************************/
/*** Check if input to state register is all zeroes. If so, ERROR! ******/
// synopsys translate_off
always @(posedge ss_clock) begin
if(state_in === 11'b0)
Mclocks.print_error("next PAR_STATE is zero ***BUG NEWS***") ;
end
// synopsys translate_on
Mflipflop_r_11 parsm_11(state,state_in,~ss_reset,ss_clock) ;
/*** Module output definitions *********************************************/
/*** I/O translation next cycle - select address for TLB input *************/
assign io_tlb_nxt = state_in[IO_TLB] | state_in[IO_TLB_TW] ;
assign data_op = state[DC_TLB] | state[DC_TLB_TW] |
state[DC_PAR] | state[WR_TLB] | state[WR_TLB_TW] ;
assign mmu_asi_op = state[ASI_OP] ;
/*** VA mux selects ********************************************************/
/* va_mux0_sel[0] - r_i_vaddr[31:12] par_cntl_sm */
/* va_mux0_sel[1] - r_d_vaddr[31:12] par_cntl_sm */
/* va_mux0_sel[2] - misc_in[31:12] asi/tw tag wrt */
/* va_mux0_sel[3] - wr_buf_3_out[31:12] par_cntl_sm */
/* */
/***************************************************************************/
/*** va_mux0_sel decode logic ********************************************/
/**************************************************************************/
/*** Select R_IVA (va_mux0_sel[0]) ***************************************/
/*** state IC_PAR *****/
/*** state IC_TLB_TW *****/
/*** I$ miss pending, and no D$ miss pending and no other select *****/
/*** and in state DC_TLB (only transition to IC_TLB). *****/
assign va_mux0_sel[0] = ((state[IC_PAR] |
(state[IC_TLB] & sel_riva &
~(dc_miss_sustain | wb_valid_x)) |
(state[IC_TLB_TW] & ~cam_reg_hld) |
(~(va_mux0_sel[1] | va_mux0_sel[2]) &
ic_miss_sustain & ~dc_miss_sustain & wb_empty &
state[DC_TLB])) &
~ss_scan_mode) ;
/**************************************************************************/
/*** Select R_DVA (va_mux0_sel[1]) ***************************************/
/*** state DC_PAR (and not a flush_iopte control space) *****/
/*** state DC_TLB_TW *****/
/*** state ASI_OP & asi_dcd3 *****/
assign va_mux0_sel[1] = (((state[DC_PAR] & ~flush_iopte) |
(state[ASI_OP] & asi_dcd3_w) |
(state[IO_TLB] & io_tlb_err) |
(state[DC_TLB_TW] & ~cam_reg_hld) |
(~(state[ASI_OP] | state[IC_TLB_TW] | state[IC_PAR] |
state[DC_TLB_TW] | state[WR_TLB_TW]) &
dc_miss_sustain & (~wb_valid_t | last_st_w) &
~(state[IO_TLB] & flush_iopte)) |
(state[WR_TLB] &
(mm_dabort | dvma_req_s | ~wb_valid_x | st_miss_x)) |
(state[DC_TLB] &
sel_rdva & (~wb_valid_t | last_st_w) &
~((ic_miss_sustain & ~pipe_moved) |
(~dc_mop_e & ~dc_mop_w) | ipar_valid))) &
~ss_scan_mode) ;
/**************************************************************************/
/*** Select MISC (va_mux0_sel[2]) ***************************************/
/*** state ASI_OP *****/
/*** state DC_PAR and control space IOPTE flush *****/
/*** state IO_TLB and control space IOPTE flush *****/
/*** state IC_TLB_TW & cam_reg_hld *****/
/*** state DC_TLB_TW & cam_reg_hld *****/
/*** state WR_TLB_TW & cam_reg_hld *****/
assign va_mux0_sel[2] = (((state[ASI_OP] & ~asi_dcd3_w & ~asi_done) |
(state[DC_PAR] & flush_iopte) |
(state[IO_TLB] & flush_iopte) |
(cam_reg_hld & (state[IC_TLB_TW] |
state[DC_TLB_TW] | state[WR_TLB_TW]))) &
~ss_scan_mode) ;
/**************************************************************************/
/*** Default select (va_mux0_sel[2]) *************************************/
assign va_mux0_sel[3] = ~(va_mux0_sel[0] | va_mux0_sel[1] | va_mux0_sel[2]) ;
/***************************************************************************/
/* va_mux1_sel[0] - va_mux0_out default */
/* va_mux1_sel[1] - data_pa[27:08] par_cntl_sm */
/* va_mux1_sel[2] - i_vaddr[31:12] par_cntl_sm */
/* va_mux1_sel[3] - d_vaddr[31:12] par_cntl_sm */
/* va_mux1_sel[4] - io_addr[31:12] par_cntl_sm */
/***************************************************************************/
/***************************************************************************/
/*** va_mux1_sel decode logic ********************************************/
assign va_mux1_sel[0] = ~(va_mux1_sel[1] | va_mux1_sel[2] |
va_mux1_sel[3] | va_mux1_sel[4]) ;
/**************************************************************************/
/*** Select Data PA (tablewalks) ******************************************/
assign va_mux1_sel[1] = va_sel_par_in & ~cam_reg_hld & sr_tw & ~tw_done &
~ss_scan_mode;
/**************************************************************************/
/*** Select IVA (va_mux1_sel[2]) *****************************************/
/*** state DC_TLB -> IC_TLB *****/
/*** state IC_TLB -> IC_TLB *****/
assign va_mux1_sel[2] = (~sel_riva &
((state[DC_TLB] &
((ic_miss_sustain & ~pipe_moved) |
~(dc_mop_e | dc_mop_w) | ipar_valid) &
~dc_miss_sustain & ~dpar_valid &
~wb_valid_t & ~dvma_req_s & ~mmasi) |
(state[IC_TLB] &
(~dvma_req_s & ~ipar_valid &
~dc_miss_sustain & ~wb_valid_x &
~(dc_mop_e & (pipe_moved | ~ic_miss_sustain)))))) &
~ss_scan_mode;
/**************************************************************************/
/*** Select DVA (va_mux1_sel[3]) *****************************************/
/*** state DC_TLB -> DC_TLB *****/
/*** No I$ miss pending OR D$ operation pending *****/
/*** No D$ miss pending OR not normal ASI *****/
/*** state ASI_OP -> DC_TLB *****/
/*** state IC_TLB -> DC_TLB for dc_mop_e cases *****/
/*** state IO_TLB -> DC_TLB *****/
/*** state WR_TLB -> DC_TLB *****/
assign va_mux1_sel[3] = ((state[DC_TLB] &
~((ic_miss_sustain & ~pipe_moved) | ipar_valid |
~(dc_mop_e | dc_mop_w)) & ~sel_rdva &
((~dc_miss_sustain & dtag_chk_done) | ~normal_asi_w) &
(~wb_valid_t | (dc_miss_sustain & last_st_w)) &
~dpar_valid & ~dvma_req_s & ~mmasi) |
(state[ASI_OP] & (asi_done | mm_dabort | r_trap_w)) |
(state[IC_TLB] &
((dc_mop_e & (pipe_moved | ~ic_miss_sustain)) &
~dvma_req_s & ~dc_miss_sustain)) |
(state[IO_TLB] & ~flush_iopte &
(~dc_miss_sustain & ~ipar_valid & ~dpar_valid &
((sbc_pa_valid & ~(r_cntl_space & r_srd_ioreq)) |
sb_par_clr | ~dvma_req_s))) |
(state[WR_TLB] & (mm_dabort | dvma_req_s))) &
~ss_scan_mode ;
/**************************************************************************/
/*** Select IOA (va_mux1_sel[4]) *****************************************/
/*** state IO_TLB -> IO_TLB *****/
/*** state DC_TLB -> IO_TLB *****/
/*** state IC_TLB -> IO_TLB *****/
/*** state IO_TLB_TW *****/
assign va_mux1_sel[4] = ((state[IO_TLB] & (dvma_req_s & ~(sbc_pa_valid &
~(r_cntl_space & r_srd_ioreq)) & ~sb_par_clr &
~flush_iopte) & ~io_tlb_err) |
(state[DC_TLB] & dvma_req_s) |
(state[IC_TLB] & dvma_req_s) |
(state[IO_TLB_TW])) & ~ss_scan_mode ;
/***************************************************************************/
/*** Mbit mux select decode ************************************************/
/*** mbit_sel[2] - ASI Ops ***/
/*** mbit_sel[1] - Tablewalks writes to TLB ***/
/*** mbit_sel[0] - Default (TLB compares) - selects tlb_mbit_cmp ***/
assign mbit_sel[2] = state[ASI_OP] & ~ss_scan_mode;
assign mbit_sel[1] = (ic_tlb_tw | dc_tlb_tw | wr_tlb_tw | io_tlb_tw) &
~tw_done & ~ss_scan_mode;
assign mbit_sel[0] = ~(mbit_sel[2] | mbit_sel[1]) ;
/***************************************************************************/
/*** Faster decode of va_mux_sel[0] for tlb_mbit_cmp ONLY! ***************/
wire va_mux1_sel0
= ~((sr_tw & ~tw_done) | va_mux1_sel[2] | va_mux1_sel[3] |
dvma_req_s | io_tlb_tw) ;
/***************************************************************************/
/*** Set the TLB Modified bit input ***************************************/
/*** Store op in E-stage and NO current read in W-stage ***/
/*** Store in W-stage ***/
/*** Write buffer has st hits in it ***/
assign tlb_mbit_cmp = (va_mux1_sel[3] & st_op_e & ~read_w) |
(va_mux1_sel0 & va_mux0_sel[1] & st_op_w) |
(va_mux1_sel0 & va_mux0_sel[3]) ;
/***************************************************************************/
/*** TLB protection bits decode ********************************************/
/*** Select Icache access type decode **************************************/
wire sel_ic_at
= (state[IC_TLB] &
~(dvma_req_s |
((dc_miss_sustain | wb_valid_x |
(dc_mop_e & (pipe_moved | ~ic_miss_sustain))) &
~dvma_req_s))) |
(state[DC_TLB] &
(((ic_miss_sustain & ~pipe_moved) | ~(dc_mop_e | dc_mop_w)) &
~dc_miss_sustain & ~dpar_valid & ~ipar_valid & ~wb_valid_t &
~dvma_req_s & ~mmasi) |
(ipar_valid & ~dc_miss_sustain & ~dpar_valid &
~wb_valid_t & ~dvma_req_s & ~mmasi)) |
state[IC_TLB_TW] |
state[IC_PAR] ;
wire [2:0] access_type
= (sel_ic_at ? {3'b011} : data_acc_s) ;
/*** Supervisor Write permission *************/
assign tlb_acc_cmp[0] = (access_type == 3'h5) | (access_type == 3'h7) ;
/*** Supervisor Read permission **************/
assign tlb_acc_cmp[1] = (access_type == 3'h1) ;
/*** Supervisor Execute permission ***********/
assign tlb_acc_cmp[2] = (access_type == 3'h3) | (access_type == 3'h7);
/*** User Write permission *******************/
assign tlb_acc_cmp[3] = (access_type == 3'h4) | (access_type == 3'h6) ;
/*** User Read permission ********************/
// assign tlb_acc_cmp[4] = (access_type == 3'h0) | (access_type == 3'h2) ;
// Changed permission decode for BUG #572
assign tlb_acc_cmp[4] = (access_type == 3'h0) ;
/*** User Execute permission *****************/
assign tlb_acc_cmp[5] = (access_type == 3'h2) | (access_type == 3'h6);
/***************************************************************************/
/*** VA mux select decode **************************************************/
/*** This mux selects the VA that bypasses the TLB ( use) *****/
/*** which means the selects are based on the current PAR state. *****/
/*** From dp_mmu.v - mux that uses selects *****/
/*** *****/
/*** CMUX5D(va_indx_mux,32,va_mux, *****/
/*** r_i_vaddr[31:00], va_mux_sel[0], *****/
/*** r_d_vaddr[31:00], va_mux_sel[1], *****/
/*** io_addr[31:00], va_mux_sel[2], *****/
/*** wr_buf_3_out[31:00], va_mux_sel[3]) *****/
/*** *****/
/*** ss_scan mode for mux control during scan, only va_mux_sel[0] on *****/
assign va_mux_sel = { ((state[WR_TLB] | state[WR_TLB_TW]) & ~ss_scan_mode),
((state[IO_TLB] | state[IO_TLB_TW]) & ~ss_scan_mode),
((state[DC_TLB] | state[DC_TLB_TW] |
state[DC_PAR] | state[ASI_OP]) & ~ss_scan_mode),
(state[IC_TLB] | state[IC_TLB_TW] | state[IC_PAR] |
ss_scan_mode) } ;
/*** PAR mux select decode *******************************/
assign par_sel[0] = state[DC_PAR] ;
assign par_sel[1] = (state[DC_PAR] | state[IC_PAR]) ;
/*** decode for IO address translated and in PAR **************************/
assign ic_tlb = state[IC_TLB] & ~bad_xlate;
assign ic_tlb_state = state[IC_TLB] ;
assign ic_tlb_tw = state[IC_TLB_TW];
assign dc_tlb = state[DC_TLB] & ~bad_xlate;
assign dc_tlb_state = state[DC_TLB] ;
assign dc_tlb_tw = state[DC_TLB_TW];
assign wr_tlb_tw = state[WR_TLB_TW] ;
assign io_tlb = state[IO_TLB];
assign io_tlb_tw = state[IO_TLB_TW] & ~ss_scan_mode;
assign ic_in_par = state[IC_TLB] | state[IC_PAR];
assign dc_in_par = state[DC_TLB] | state[DC_PAR] | state[WR_TLB];
assign wr_tlb = state[WR_TLB] ;
assign ic_par_state = state[IC_PAR] ;
assign dc_par_state = state[DC_PAR] ;
/*** RMMU tablewalk decode ***********************************************/
/*** I-cache or D-cache tablewalk and no trap (due to PAR change) *****/
assign sr_tw = (dc_tlb_tw | (ic_tlb_tw & ~mm_iabort) |
state[WR_TLB_TW] | (state[ASI_OP] & asi_dcd3_w & ~asi_done)) &
~ss_scan_mode;
assign hold_par = (tw_par & ~ld_par_tw) | (~tw_par & ~tlb_hit) ;
assign ld_par = ~hold_par ;
/***************************************************************************/
/*** dc_par indicates that PAR has a vaild D-cache address to ******/
/*** start a memory operation with next cycle. ******/
/*** NOTE: we gate dc_par and ic_par with dvma_req to prevent the ******/
/*** the case where dvma_req has forced par to the TLB state, ******/
/*** marb and issue_reqs have been issued. DVMA should pre-empt ******/
/*** any cpu op even if it is xlated and ready to go. ******/
wire dc_par
= ~(dvma_req_s & ~ldst_block) &
((dc_tlb & ~r_trap_w & set_dpar) |
(state[DC_PAR] & (~r_trap_w | wb_valid_x | dc_alloc_pnd)) |
(state[WR_TLB] & tlb_hit & ~bad_xlate & wb_valid_x)) ;
This page: |
Created: | Thu Aug 19 11:59:58 1999 |
| From: |
../../../sparc_v8/ssparc/mmu/m_mmu_cntl/rtl/rl_par_cntl.v
|