wire dc_par_reg
;
Mflipflop_r_1 dc_par_ff_1(dc_par_reg,dc_par,~ss_reset,ss_clock) ;
/***************************************************************************/
/*** Qualify r_dc_par with reg'd trap signal ***/
/*** (except when outstanding writes, or write allocates) ***/
assign r_dc_par = dc_par_reg & (~r_trap_w | wb_valid_x | dc_alloc_pnd) ;
/***************************************************************************/
/*** ic_par indicates that PAR has a vaild I-cache address to ******/
/*** start a memory operation with next cycle. ******/
wire ic_par
= ~dvma_req_s & ((state[IC_TLB] & tlb_hit & ic_miss &
~bad_xlate & ~wb_valid_t & ~dc_miss_sustain) | state[IC_PAR]);
wire ic_par_reg
;
Mflipflop_r_1 ic_par_ff_1(ic_par_reg,ic_par,~ss_reset,ss_clock) ;
/***************************************************************************/
/*** Qualify r_ic_par with outstanding D$ operation ***/
/*** This is necessary since ic_miss and dc_miss could be asserted ***/
/*** in the same cycle when the current PAR state is IC_TLB. This ***/
/*** would allow the I$ address to be translated 1st, but the D$ mop ***/
/*** must be issued 1st. ***/
assign r_ic_par = ic_par_reg & ~r_dc_miss & ~state[DC_TLB] & ~dvma_req_x;
/***************************************************************************/
wire sb_par = state[IO_TLB] & ~tlb_miss & dvma_req_s ;
assign tw_par = sr_tw | state[IO_TLB_TW] ;
wire r_sb_par;
Mflipflop_r_1 sb_par_ff_1(r_sb_par,sb_par,~ss_reset,ss_clock) ;
wire r_tw_par;
Mflipflop_r_1 tw_par_ff_1(r_tw_par,tw_par,~ss_reset,ss_clock) ;
assign req_pending = (r_sb_par | r_dc_par | r_ic_par |
(r_tw_par & tw_read_req)) & r_mem_space ;
/***************************************************************************/
/*** Memory debug signals ***/
/*** ***/
/*** mm_mem_dbg[1:0] | current access ***/
/*** -----------------+------------------------ ***/
/*** 00 | Instruction cache access ***/
/*** 01 | Data cache access ***/
/*** 10 | tablewalk access ***/
/*** 11 | other memory accesses ***/
assign mm_mem_dbg = {~(ic_par_reg | dc_par_reg),
~(ic_par_reg | tw_par)} ;
/***************************************************************************/
/*** Bad translate cycle decode *******************************************/
/*** The cycle after iu_pipe_hold was asserted always is a bad cycle ***/
/*** to translate, because the previous cycle selected the wrong ***/
/*** virtual address. For the D$, the cycle iu_pipe_hold -> 1, the ***/
/*** E-stage DVA was loaded into the TLB, but the MMU wants the held ***/
/*** W-stage DVA. Since we can't use iu_pipe_hold as a mux select, ***/
/*** due to timing constraints, the MMU invalidates the translation ***/
/*** based on the bad VA. ***/
/*** For I$ xlates we have the same problem, but the c\bad cycle is ***/
/*** is the cycle after ic_miss is asserted. The IU places npc on the ***/
/*** iva_g bus, but we can't use ic_miss to switch the va mux in time.***/
/*** So,we call the next cycle a bad xlate cycle. ***/
wire r_pipe_moved;
Mflipflop_r_1 pipe_moved_ff_1(r_pipe_moved,pipe_moved,~ss_reset,ss_clock) ;
wire st_req
= dc_issue_req & mreq_st ;
wire r_st_req
;
Mflipflop_r_1 st_req_ff_1(r_st_req,st_req,~ss_reset,ss_clock) ;
wire bad_ixlate_in
= ic_miss & ~ic_miss_sustain;
wire r_bad_ixlate
;
Mflipflop_r_1 bad_ixlateff_1(r_bad_ixlate,bad_ixlate_in,~ss_reset,ss_clock) ;
wire r_sel_rdva
;
/***************************************************************************/
/*** NEED to review these cases !!! *****/
/***************************************************************************/
wire dc_after_io_issue_in
= r_sb_par & mem_issue_req & r_sb_par;
wire dc_after_io_issue
;
MflipflopR_1 dc_after_io_issue_ff_1(dc_after_io_issue,dc_after_io_issue_in, ss_clock,1'b0,ss_reset) ;
wire wr_tw_abort_in
= tw_abort & wr_tlb;
wire r_wr_tw_abort
;
Mflipflop_r_1 wr_tw_abort_ff_1(r_wr_tw_abort,wr_tw_abort_in,~ss_reset,ss_clock) ;
assign bad_xlate = (r_pipe_moved & ~pipe_moved) | // bad address in TLB
(r_st_req) | // reg'd store mem req
(r_bad_ixlate & state[IC_TLB]) | // bad ic xlate cycle
(r_sel_rdva & state[DC_TLB]) | // bad dc xlate cycle
r_flush_entry | // cycle after no compare
mm_dabort | mm_iabort |
tw_abort | r_wr_tw_abort |
(asi_dcd3_w & state[DC_TLB] & ~(flush_in | probe_in)) |
// probe or flush >5
dc_after_io_issue; // cyc after IO_TLB & issue_req
/***************************************************************************/
/*** Select Reg'd IVA decode **********************************************/
/*** If the pipe is held, and there is a I$ op in the f-stage, and ***/
/*** the I$ sm has not been in the IDLE state, then select r_iva ***/
wire itag_chk_hld
= ~(ic_idle | pipe_moved);
wire r_itag_chk
;
MflipflopR_1 itag_chk_ff_1(r_itag_chk,ic_idle, ss_clock,itag_chk_hld,ss_reset) ;
assign itag_chk_done = ~dc_mop_w | (pipe_moved ? ic_idle : r_itag_chk) ;
assign sel_riva = (~pipe_moved & ~itag_chk_done) | ic_miss_sustain ;
/***************************************************************************/
/*** Select Reg'd DVA decode **********************************************/
/*** If the pipe is held, and there is a D$ op in the W-stage, and ***/
/*** the D$ sm has not been in the IDLE state, then select r_dva ***/
wire dtag_chk_hld
= ~(dcc_idle | pipe_moved);
wire r_dtag_chk
;
MflipflopR_1 dtag_chk_ff_1(r_dtag_chk,dcc_idle, ss_clock,dtag_chk_hld,ss_reset) ;
/*** Consider the D-cache tag lookup done if: ***/
/*** There is no D-cache operation in the W-stage ***/
/*** The pipe moved last cycle (not being held) ***/
/*** Went to the dcc idle state ***/
assign dtag_chk_done = ~dc_mop_w | pipe_moved | r_dtag_chk ;
assign sel_rdva = ~pipe_moved & ~dtag_chk_done ;
Mflipflop_r_1 r_sel_rdva_ff_1(r_sel_rdva,sel_rdva,~ss_reset,ss_clock) ;
/***************************************************************************/
/*** IPAR and DPAR valid bits *********************************************/
wire ipar_valid_in
= (ic_tlb & ic_miss & tlb_hit & ~bad_xlate) |
(ipar_valid & ~(ic_issue_req | mmu_asi_op)) ;
Mflipflop_r_1 ipar_vld_ff_1(ipar_valid,ipar_valid_in,~ss_reset,ss_clock) ;
/***************************************************************************/
assign set_dpar = tlb_hit & ((pipe_moved ? dc_miss : dc_miss_sustain) &
(~bad_xlate & ~asi_dcd3 & normal_asi_w & ~mmasi &
(~wb_valid_t | last_st_w))) ;
wire dpar_valid_in
= (dc_tlb & set_dpar &
~(dc_issue_req | (r_trap_w & ~wb_valid_x))) |
(wr_tlb & tlb_hit & ~bad_xlate & ~dpar_valid &
~mmasi & wb_valid_t) |
(dpar_valid & ~(dc_issue_req | state[ASI_OP] |
(r_trap_w & ~(wb_valid_x | dc_alloc_pnd)))) ;
/***** Do we REALLY need to clear dpar_valid on state[ASI_OP]??? **********/
Mflipflop_r_1 dpar_vld_ff_1(dpar_valid,dpar_valid_in,~ss_reset,ss_clock) ;
/***************************************************************************/
/*** Decode a D-cache allocate pending bit, used to mask traps when ***/
/*** a cache allocate is pending for a store miss to a cacheable page ***/
/*** Only cleared on a dc_issue_req. ***/
wire dc_alloc_pnd_in
= (mm_dstat_avail & wb_valid_x & mm_cache_stat) |
(dc_alloc_pnd & ~dc_issue_req) ;
Mflipflop_r_1 dc_alloc_ff_1(dc_alloc_pnd,dc_alloc_pnd_in,~ss_reset,ss_clock) ;
/***************************************************************************/
/*** Monitor for checking VA mux selects in sync with PAR state ***********/
// synopsys translate_off
always @(posedge ss_clock) begin
if (~ss_reset & `MMU_CNTL.mmu_en) begin
case (state_in)
D_DC_TLB:
if (~(va_mux1_sel[3] | // sel iu_dva
(va_mux1_sel[0] & va_mux0_sel[1]) | // sel r_dva
(va_mux1_sel[0] & va_mux0_sel[2] & flush_iopte) |
(va_mux1_sel[0] & va_mux0_sel[3] & (last_st_w |~wb_empty)) |
(iu_pipe_hold & pipe_moved))) // bad xlate cycle
Mclocks.print_error("BAD VA mux select for next PAR state -DC_TLB") ;
D_DC_TLB_TW:
if (~(va_mux1_sel[1] | (va_mux1_sel[0] &
(va_mux0_sel[2] | va_mux0_sel[1]))) & state[DC_TLB_TW])
Mclocks.print_error("BAD VA mux select for next PAR state -DC_TLB_TW") ;
// D_DC_PAR:
// if (~(va_mux1_sel[3] | (va_mux1_sel[0] & va_mux0_sel[1])))
// Mclocks.print_error("BAD VA mux select for next PAR state -DC_PAR") ;
D_IC_TLB:
if (~((va_mux1_sel[2] & ~ic_miss_sustain) | (va_mux1_sel[0] & va_mux0_sel[0]) |
(iu_pipe_hold & pipe_moved))) // bad xlate cycle
Mclocks.print_error("BAD VA mux select for next PAR state -IC_TLB") ;
D_IC_TLB_TW:
if (~(va_mux1_sel[1] | (va_mux1_sel[0] &
(va_mux0_sel[2] | va_mux0_sel[0]))) & state[IC_TLB_TW])
Mclocks.print_error("BAD VA mux select for next PAR state -IC_TLB_TW") ;
// D_IC_PAR:
// if (~(va_mux1_sel[2] | (va_mux1_sel[0] & va_mux0_sel[0])))
// Mclocks.print_error("BAD VA mux select for next PAR state -IC_PAR") ;
D_IO_TLB:
if (~(va_mux1_sel[4]) |
(va_mux1_sel[0] & va_mux0_sel[2] & flush_iopte))
Mclocks.print_error("BAD VA mux select for next PAR state -IO_TLB") ;
D_IO_TLB_TW:
if (~(va_mux1_sel[4]) | (va_mux1_sel[0] & va_mux0_sel[2]))
Mclocks.print_error("BAD VA mux select for next PAR state -IO_TLB_TW") ;
D_WR_TLB:
if (~((va_mux1_sel[0] & va_mux0_sel[3]) |
(va_mux0_sel[1] & va_mux1_sel[0] & (~wb_valid_x | sel_rdva)) |
(va_mux1_sel[3] & wb_valid_t & ~wb_valid_x) |
(iu_pipe_hold & pipe_moved))) // bad xlate cycle
Mclocks.print_error("BAD VA mux select for next PAR state -WR_TLB") ;
D_WR_TLB_TW:
if (~(va_mux1_sel[1] | (va_mux1_sel[0] &
(va_mux0_sel[2] | va_mux0_sel[3]))))
Mclocks.print_error("BAD VA mux select for next PAR state -WR_TLB_TW") ;
D_ASI_OP:
if (~(va_mux1_sel[3] |
(va_mux1_sel[0] & (va_mux0_sel[1] | va_mux0_sel[2]))) &
state[ASI_OP])
Mclocks.print_error("BAD VA mux select for next PAR state -ASI_OP") ;
endcase
end // reset test
end // always
// synopsys translate_on
/***************************************************************************/
endmodule
This page: |
Created: | Thu Aug 19 11:59:59 1999 |
| From: |
../../../sparc_v8/ssparc/mmu/m_mmu_cntl/rtl/rl_par_cntl.v
|