/****************************************************************************/
/*** TLB tag input level bits - Level bits that are input to TLB CAM ***/
/*** Only SET cam_lvl bits when writing a PTE (~ptp_in) ***/
/*** Decode for raw TLB level bits from tag (software tag[12:10]) ***/
/*** ***/
/*** cam_lvl[2:0] tlb_lvl_dcd[1:0] (PTE level) ***/
/*** ------------ ---------------- ----------- ***/
/*** 111 00 level-0 ***/
/*** 011 01 level-1 ***/
/*** 001 10 level-2 ***/
/*** 000 11 level-3 ***/
/*** 000 11 IO-PTE ***/
assign tlb_cam_lvl[2] = ((flush_entry) &
(flush_tlb_ctx | flush_tlb_all | flush_ioall)) |
(state[PTE_FLUSH] & flush_crs ) |
(state[PTE_FLUSH1] & flush_crs & virt_ptp2) |
(~flush_iopte & dvma_ioflush) |
(ldtlb_tag_tw & ~ptp_in & ~tlb_ram_lvl[2]) ;
assign tlb_cam_lvl[1] = ((flush_entry) &
(flush_tlb_ctx | flush_tlb_all | flush_ioall |
flush_tlb_reg)) |
(state[PTE_FLUSH] & flush_crs) |
(state[PTE_FLUSH1] & flush_crs & virt_ptp2) |
(~flush_iopte & dvma_ioflush) |
(ldtlb_tag_tw & ~ptp_in & ~tlb_ram_lvl[1]) ;
assign tlb_cam_lvl[0] = ((flush_entry) &
(flush_tlb_ctx | flush_tlb_all | flush_ioall |
flush_tlb_seg | flush_tlb_reg)) |
(state[PTE_FLUSH] &
((virt_ptp2 & ~r_flush_entry) | flush_crs)) |
(state[PTE_FLUSH1] & flush_crs & virt_ptp2) |
(~flush_iopte & dvma_ioflush) |
(ldtlb_tag_tw & ~ptp_in & ~tlb_ram_lvl[0]) |
(state[PTBL1] & virt_ptp2 ) |
(state[PT1WRT] & virt_ptp2 &
(r_mdata_et == 2'b01)) |
((state[VPTP_HIT] | state[IDLE]) &
~(flush_entry | dvma_ioflush | strt_tw_for_m) &
virt_ptp2 & tw_par & ~probe_entire);
/*** Modified bit input - input for TLB modified bit (both data and select)*/
assign m_in = (tw_par & set_m_on_tw);
// Msb state input bit indicates table walk next cycle
assign tw_tlb_nxt = ~state_in[IDLE];
/*** Table walk Level bits - indicates current "level" of tablewalk. ******/
/*** Must be asserted for both compare state, and when writing to TLB, ****/
/*** because PAR is loaded in parallel with TLB update. ****/
/*** level decode ROOT - 01 ***/
/*** LVL1 - 10 ***/
/*** LVL2 - 11 ***/
/*** LVL3 - 00 ***/
/*** IO - 00 ***/
assign tw_sm_lvl[1] = state[PTBL1] | state[PT1WRT] | state[PTBL3] |
state[PTBL2] | state[PT2WRT] | state[VPTP_HIT];
assign tw_sm_lvl[0] = state[ROOT] | state[RTWRT] | state[PTBL3] |
state[PTBL2] | state[PT2WRT] | state[VPTP_HIT];
/*** Tablewalk TLB write state - qualifies that parity is valid **********/
assign io_tw_wrt = state[INIT_PAR_WRT];
assign sr_tw_wrt = (state[RTWRT] | state[PT1WRT] |
state[PT2WRT] | state[PT3WRT]) ;
/*** Latch the status during each level write (only time errors occur) ***/
wire err_lvl_hld
= ~sr_tw_wrt ;
wire [1:0] tw_err_lvl;
MflipflopR_2 tw_err_lvl_ff_2(tw_err_lvl,tw_sm_lvl,ss_clock,err_lvl_hld,ss_reset) ;
/*** PAR initialization state decode - used for mux selects. **************/
assign tw_init_par = state[INIT_PAR] | state[RTMEM] |
state[INIT_PAR_MEM] | state[INIT_PAR_WRT];
/*** TLB hold input - misnomer, flush entry control - piped 1 cycle. ******/
wire tlb_flush_unbuf
= ((state[IDLE]) & (strt_tw_for_m | dvma_ioflush |
(flush_entry))) |
(state[PTE_FLUSH] & flush_crs) |
(state[PTE_FLUSH1] & flush_crs & virt_ptp2) |
((state[ERR_ADR] | state[ERR_XLT]) |
(state[UPDATE_C] & r_acc_err_tw)) ;
JBUFC slow_buf9(tlb_flush_unbuf,buf_term3
);
JBUFD slow_buf8(buf_term3,tlb_flush);
wire flush_done_in
= (flush & dc_tlb_tw &
((state[PTE_FLUSH] & ~flush_crs) |
(state[PTE_FLUSH1] & ~virt_ptp2) |
state[PTE_FLUSH2])) | (flush_done & ~asi_done) ;
wire flush_done;
Mflipflop_r_1 flush_done_ff_1(flush_done,flush_done_in,~ss_reset,ss_clock) ;
assign co_in = tlb_flush & flush & flush_tlb_all ;
/*** Update TLB - actually used to disable compare decode for next cycle. **/
assign tlb_update = (state[RTMEM] |
state[PT1MEM] |
state[PT2MEM] |
state[PT3MEM] |
(io_tlb_tw & ~state[ERR_XLT] &
~(state[INIT_PAR_WRT] & (r_mdata_et == 2'b10))) |
((state[RTWRT] |
state[PT1WRT] |
state[PT2WRT]) &
~(r_mdata_et == 2'b01)) |
(state[PRB_DONE] & ~mm_misc2cf & probe_hit) |
// (state[PTBL2] & ~(probe_lvl2 & ~tlb_miss)) |
(state[PTBL2] & tlb_miss) |
(state[PTBL1] & tlb_miss) |
(state[ROOT] & tlb_miss) |
(state[PTE_TAG] & r_tw_err) );
assign tw_rewrite_cam = (state[RTWRT] |
state[PT1WRT] |
state[PT2WRT]) &
~(r_mdata_et == 2'b01);
/*** TRCR hold - freezes the TLB address counter. *************************/
assign tw_trcr_hld = (state[RTWRT] |
state[PT1WRT] |
state[PT2WRT] |
state[PT3WRT] |
state[INIT_PAR_WRT] |
((state[RTMEM] |
state[PT1MEM] |
state[PT2MEM] |
state[PT3MEM] |
state[INIT_PAR_MEM]) &
(tdata_rdy_in | tdata_rdy)) | (state[UPDATE2]) |
(state[PTE_TAG]) | (state[UPDATE]) |
(state[UPDATE_C]) | (state[PRB_DONE]) |
(state[PTE_TAG_U]) |
(dc_tlb_tw & (probe_lvl0 |
probe_lvl1 | probe_lvl2 | probe_lvl3))) ;
/*** Table walk Address error state decode ********************************/
assign tw_addr_err = (state[ERR_ADR]);
/*** Table walk Translation error state decode ****************************/
assign tw_xlat_err = (state[ERR_XLT]);
/*** Probe data ready - kicks-off marb_sm to start read of probe data *****/
assign tw_prb_drdy = state[PRB_DONE] ;
/*** Probe error decode - selects "zero" as return data on probe. *********/
assign tw_prb_err = (probe &
((state[RTWRT] &
~((probe_lvl0 & ~(r_mdata_et == 2'b11)) |
(~probe_lvl0 & (r_mdata_et == 2'b01)) |
(probe_entire & ((r_mdata_et == 2'b10) |
(r_mdata_et == 2'b01))))) |
(state[PT1WRT] &
~((probe_lvl1 & ~(r_mdata_et == 2'b11)) |
(~probe_lvl1 & (r_mdata_et == 2'b01)) |
(probe_entire & ((r_mdata_et == 2'b10) |
(r_mdata_et == 2'b01))))) |
(state[PT2WRT] &
~((probe_lvl2 & ~(r_mdata_et == 2'b11)) |
(~probe_lvl2 & (r_mdata_et == 2'b01)) |
(probe_entire & ((r_mdata_et == 2'b10) |
(r_mdata_et == 2'b01))))) |
(state[PT3WRT] &
~((probe_lvl3 & ~(r_mdata_et[0] == 1'b1)) |
(probe_entire & (r_mdata_et == 2'b10)))) |
(enbl_soft_tw)));
/*** Probe Done - Indicates last state(s) of probe. ***********************/
assign probe_done = (state[PRB_DONE]) | (state[PRB_CLR]);
/*** Probe Invalid - Force ET field = 00 on probe of Invalid PTE. *********/
assign probe_invalid = (probe & (tw_perr |
((state[RTWRT] &
probe_lvl0 & (r_mdata_et == 2'b00)) |
(state[PT1WRT] &
probe_lvl1 & (r_mdata_et == 2'b00)) |
(state[PT2WRT] &
probe_lvl2 & (r_mdata_et == 2'b00)) |
(state[PT3WRT] &
probe_lvl3 & (r_mdata_et == 2'b00)))));
/*** Supervisor bit input during tablewalks *******************************/
assign tw_sin = (state[IDLE] & flush_tlb_all) |
(state[PTE_FLUSH] & flush_crs) |
(state[PTE_FLUSH1] & flush_crs & virt_ptp2) |
state[INIT_PAR_MEM] |
(state[PT3MEM] & // Level 3 pte for Sys page
(mdata_in_acc == 2'b11)) |
((state[PT1WRT] | // Level 1 pte for Sys page
state[PT2WRT]) & // Level 2 pte for Sys page
(r_mdata_et == 2'b10) &
(r_mdata_acc == 2'b11)) ;
/*** Tablewalk PTE check state - qualifies that ACC field is valid *******/
wire tw_pte_chk_in
= state[UPDATE] & ~probe ;
wire tw_pte_chk;
Mflipflop_r_1 tw_pte_chk_ff_1(tw_pte_chk,tw_pte_chk_in,~ss_reset,ss_clock) ;
/*** TLB CAM output register hold decode *********************************/
/*** Hold the TLB CAM output after a tablewalk lookup. The address *****/
/*** from the lookup will be used to write the entry's tag when the *****/
/*** page enrty is returned from memory (for PTPs). *****/
assign cam_reg_hld = asi_cam_read | state[PT1MEM] |
(state[PT2MEM] & ~virt_ptp2) |
(probe_hit & (state[PTE_TAG] | state[PRB_DONE]));
/*** TLB RAM output register hold decode *********************************/
/*** Hold the TLB RAM output - [holds HIT data for probe read] *****/
/*** This decode needs work!!! just started as place holder *****/
assign ram_reg_hld = asi_ram_read | (probe & (state[UPDATE] | state[PRB_CLR])) |
(probe_hit & (state[PTE_TAG] | state[PRB_DONE]));
// Register the fact that we hit to the TLB on a level probe.
// If we hit the PTE/PTP is held in the ram_reg and passed thru
// the TLB ram via a write to the TLB (note this write is with the V=0)
// If we miss to the TLB the PTE/PTP comes from memory, and the PTE/PTP
// is held in the DP and pushed out thru pa_mux_rd to the misc bus.
wire probe_lvl
= probe_lvl0 | probe_lvl1 | probe_lvl2 | probe_lvl3;
wire probe_hit_in
= (probe_hit & ~asi_done) |
(state[ROOT] & ~tlb_miss & probe_lvl0) |
(state[PTBL1] & ~tlb_miss & probe_lvl1) |
(state[PTBL2] & ~tlb_miss & probe_lvl2) |
(state[PTBL3] & ~tlb_miss & probe_lvl3) |
(state[INIT_PAR] & ~tlb_miss & probe_lvl2 & virt_ptp2) |
(state[INIT_PAR] & ~tlb_miss & probe_entire) ;
Mflipflop_r_1 probe_hit_ff_1(probe_hit,probe_hit_in,~ss_reset,ss_clock) ;
wire lvl_probe_hld_in
= (lvl_probe_hld & ~asi_done) |
(((state[RTMEM] & probe_lvl0) |
(state[PT1MEM] & probe_lvl1) |
(state[PT2MEM] & probe_lvl2) |
(state[PT3MEM] & probe_lvl3)) & tdata_rdy );
MflipflopR_1 lvl_probe_hld_ff_1(lvl_probe_hld,lvl_probe_hld_in, ss_clock,1'b0,ss_reset) ;
//
// set the v bit to be written into tlb as always 1 except for
// level probes operations.
assign tw_tlb_vbit = ~((state[PRB_DONE] & probe_hit) |
(ldtlb_tag_tw & (tw_prb_err | probe_lvl)));
//
// force cam reg to drive cam_data_in on level probe hit to PRB_DONE
assign tlb_cam_reload = probe_hit & cam_reg_hld ;
// assign tlb_cam_reload = ~tw_tlb_vbit & cam_reg_hld ;
// decode root_tw, pt1_tw & pt2_tw
assign root_tw = state[RTMEM] | state[RTWRT];
assign pt1_tw = state[PT1MEM] | state[PT1WRT];
assign pt2_tw = state[PT2MEM] | state[PT2WRT];
endmodule
This page: |
Created: | Thu Aug 19 11:59:37 1999 |
| From: |
../../../sparc_v8/ssparc/mmu/m_mmu_cntl/rtl/rl_tw_sm.v
|