task sfsr_display;
if (ld_sfsr) begin
$display("\n!!! SFSR loaded with : %0h\n",sfsr_disp);
end
endtask
// synopsys translate_on
/* */
/************************************************************************/
/*** Data Error reporting logic *****/
wire dacc_err
= (((tw_xlat_err & dc_tlb_tw & ~probe) |
sb_dacc_err) & ~no_fault) |
wb_xlat_err | asi_err_cntl ;
wire dacc_err_hld
= ~(dacc_err | ~iu_pipe_hold);
wire mm_dacc_err;
MflipflopR_1 dacc_err_ff_1(mm_dacc_err,dacc_err,ss_clock,dacc_err_hld,ss_reset) ;
assign asi_err_cntl = cntrl_spc_err & ~mm_dabort;
/************************************************************************/
/*** Data Exception reporting logic *****/
wire dacc_exc
= (((r_dc_tlb & r_dc_miss & (priv_err_x | prtct_err_x) &
((read_w & ~wb_valid_x) | st_miss_x)) |
(dc_tlb_tw & r_acc_err_tw) |
(dc_tlb_tw & tw_addr_err)) & ~no_fault) ;
wire dacc_exc_hld
= ~(dacc_exc | ~iu_pipe_hold);
wire mm_dacc_exc;
MflipflopR_1 dacc_exc_ff_1(mm_dacc_exc,dacc_exc,ss_clock,dacc_exc_hld,ss_reset) ;
/************************************************************************/
/*** Data access Miss reporting logic *****/
wire dacc_miss = ((r_dc_tlb & r_dc_miss & r_tlb_miss & enbl_soft_tw &
((read_w & ~wb_valid_x) | st_miss_x)) |
(r_wr_tlb & r_tlb_miss & enbl_soft_tw) |
dmiss_for_m) ;
wire dacc_miss_hld
= ~(dacc_miss | ~iu_pipe_hold);
wire mm_dacc_miss;
MflipflopR_1 dacc_miss_ff_1(mm_dacc_miss,dacc_miss,ss_clock,dacc_miss_hld,ss_reset) ;
/************************************************************************/
/*** Watchpoint trap decode logic *****/
/*** Gate data access watchpoint traps with the fact that an *****/
/*** instruction cache access is not being selected. *****/
/*** *****/
/*** Must hold iacc_wp_trig if pipe stalls in E-stage *****/
/*** (gate w/ iacc_wp_e so non-instr traps don't get held) *****/
wire iacc_wp_trig_in
= pcntr_a_co & iacc_wp_e ;
// Changed hold term for BUG #591 fix
// wire iacc_wp_trig_hld = ~(iacc_wp_trig_in | ~iu_pipe_hold) ;
wire iacc_wp_trig
;
MflipflopR_1 pca_co_hld_ff_1(iacc_wp_trig,iacc_wp_trig_in, ss_clock,iu_pipe_hold,ss_reset) ;
/*** Select correct trigger for Instruction based Watchpoint traps *****/
// wire wp_trig_in = pcntr_a_co & ~dpar_valid ;
//
// REGWIRE wp_trig_reg;
// REGRNH(wp_trig_ff,1,wp_trig_reg,wp_trig_in,ss_clock,ss_reset)
//
// wire wp_trig = wp_trig_reg & ~dpar_valid |
//
// Change wp_trap decode to fix BUG #591 (moved qualification to dp_mmu)
//
wire wp_trap
= wp_trap_en & ((mmu_brkpt_en[0] & (va_src_sel == 2'b00)) ?
(iacc_wp_trig | pcntr_a_co) : pcntr_a_co) ;
// Old hold term
// wire wp_trap_hld = ~(wp_trap | ~iu_pipe_hold);
//
// New hold term for BUG #591 fix
wire wp_trap_hld
= (iva_wp_sel | ~wp_trap) & iu_pipe_hold ;
wire mm_dacc_wp;
MflipflopR_1 watchpt_ff_1(mm_dacc_wp,wp_trap,ss_clock,wp_trap_hld,ss_reset) ;
/* */
/*************************************************************************/
/*** IO Range - IO virtual address mask error checking ***/
wire io_va_vld
= io_op & (r_srd_ioreq | r_sxlate_ioreq);
wire va_range_err
= ~(r_ioadr[31] & (r_ioadr[30] | io_range_sel[7]) &
(r_ioadr[29] | io_range_sel[6]) &
(r_ioadr[28] | io_range_sel[5]) &
(r_ioadr[27] | io_range_sel[4]) &
(r_ioadr[26] | io_range_sel[3]) &
(r_ioadr[25] | io_range_sel[2]) &
(r_ioadr[24] | io_range_sel[1]));
wire io_va_err
= ~io_mmu_bp & va_range_err;
wire io_bp_enbl_in
= io_cr[0] & io_bp_enbl & ~sb_sbslot[2] &
~r_ioadr[31] & ~r_ioadr[30];
wire r_io_bp_enbl
;
Mflipflop_r_1 io_bp_enbl_ff_1(r_io_bp_enbl,io_bp_enbl_in,~ss_reset,ss_clock) ;
assign io_mmu_bp = r_io_bp_enbl & io_va_vld ;
wire r_perr_dcd_mask
;
wire r_perr_dcd_mask_in
= ((r_perr_dcd & msm_sreq) | r_perr_dcd_mask) &
marb_busy;
Mflipflop_r_1 perr_dcd_mask_ff_1(r_perr_dcd_mask,r_perr_dcd_mask_in,~ss_reset,ss_clock) ;
wire sb_err_in
= ((r_perr_dcd & ~r_perr_dcd_mask & msm_sreq & ~mop_mreq[3]) |
io_tlb_walk_perr |
(tw_xlat_err & io_tlb_tw & ~r_io_tlb_walk_perr) |
(io_va_err & io_va_vld & io_cr[0]) |
(io_prtct_err));
wire io_tlb_err = (io_va_err & io_va_vld & io_cr[0]);
wire mm_sb_err;
Mflipflop_r_1 sb_err_ff_1(mm_sb_err,sb_err_in,~ss_reset,ss_clock) ;
/*************************************************************************/
/* SFAR - Synchronous Fault Address Register mux select decode. */
assign sfar_write = (asi_dcd4 & (r_dva_12_8 == 5'h14) & mmstben_aarb);
assign sfar_read = (asi_dcd4 & (r_dva_12_8 == 5'h04) & mmreg_rd_asi) ;
/* */
/*************************************************************************/
/* AFSR - Asynchronous Fault Status Register. */
/*****************************************************************************/
/* AFSR register definition */
/* */
/* +---+---+---+---+-----+---+------+---+---+---+--------------------------+ */
/* |ERR| LE| TO| BE| SIZ | S | 1000 | ME| RD|FAV| rsvd | */
/* +---+---+---+---+-----+---+------+---+---+---+--------------------------+ */
/* 31 30 29 28 27 25 24 23 20 19 18 17 16 00 */
/* */
/* af_status definition */
/* +---+---+---+---+-----+---+----------+---+---+--------------------------+ */
/* |ERR| LE| TO| BE| SIZ | S | | RD|FAV| | */
/* +---+---+---+---+-----+---+----------+---+---+--------------------------+ */
/* 09 08 07 06 05 03 02 01 00 */
/* */
/* Multiple error bit register separately */
/*****************************************************************************/
/*** Track supervisor bit with contents of PAR. *****************************/
wire ipar_sbit
;
wire dpar_sbit
;
wire sbit_in
= ((at_t[0] | bypass_mmu_asi) &
~(ic_par_state | dc_par_state)) |
(ic_par_state & ipar_sbit) |
(dc_par_state & dpar_sbit );
wire par_sbit
;
MflipflopR_1 par_sbit_ff_1(par_sbit,sbit_in,ss_clock,hold_par,ss_reset) ;
MflipflopR_1 ipar_sbit_ff_1(ipar_sbit,sbit_in,ss_clock,ipar_valid,ss_reset) ;
MflipflopR_1 dpar_sbit_ff_1(dpar_sbit,sbit_in,ss_clock,dpar_valid,ss_reset) ;
/*** Track supervisor bit with memory request. *****************************/
wire afsr_sbit_in
;
MflipflopR_1 afsr_sbit_in_ff_1(afsr_sbit_in,par_sbit,ss_clock, ~io_issue_req,ss_reset) ;
/*****************************************************************************/
/*** Track cacheable bit with contents of PAR. *************************/
wire r_cbit
;
MflipflopR_1 par_cbit_ff_1(r_cbit,(cbit_in & ~bypass_mmu_asi), ss_clock,hold_par,ss_reset) ;
/*** Force cache-able bit OFF for I/O and Control space accesses *************/
assign par_cbit = r_cbit & ~((r_dc_in_par | r_ic_in_par) &
(r_io_space | r_cntl_space | r_pci_space)) ;
wire ipar_cbit;
MflipflopR_1 ipar_cbit_ff_1(ipar_cbit,(cbit_in & ~bypass_mmu_asi), ss_clock,ipar_valid,ss_reset) ;
wire dpar_cbit;
MflipflopR_1 dpar_cbit_ff_1(dpar_cbit,(cbit_in & ~bypass_mmu_asi), ss_clock,dpar_valid,ss_reset) ;
/*****************************************************************************/
wire afsr_me
;
wire [09:00] afsr_out
;
wire [31:00] afsr
= {afsr_out[09:02],4'b1000,afsr_me,
afsr_out[01:00],17'b0};
assign mm_lvl15_int_l = ~(afsr[31] | mfsr[31]) ;
wire af_err_in
= (((~r_sb_err_type[1] | ~r_sb_err_type[0])
& sb_wrt_err) | sb_cp_le) ;
wire af_err
= af_err_in | afsr[31] ;
wire af_me_bit
= afsr_me | (afsr[31] & af_err_in);
/*****************************************************************************/
/*** Decode to determine when PIO read data is available (pending xfer) ****/
/*** this is necessary for determing when the AFSR.fav bit should be ****/
/*** set. If a read xfer pending is active, then AFSR.fav = 1. ****/
wire pio_rd_active
;
wire pio_rd_in
= pio_data_rcvd | (pio_rd_active & ~io_issue_req) ;
Mflipflop_r_1 pio_rd_ff_1(pio_rd_active,pio_rd_in,~ss_reset,ss_clock) ;
wire afsr_fav
= ~(sb_cp_le & sb_cyc_pnd & ~pio_rd_active) ;
wire [09:00] af_status
= {af_err,
sb_cp_le, /* SBus late error*/
sb_cp_to, /* SBus time-out*/
sb_cp_be, /* SBus error*/
sb_errsize, /* 3-bit SBus size field*/
afsr_sbit_in, /* supervisor bit*/
~sb_wrt_err, /* write operation bit*/
afsr_fav}; /* fault address valid */
wire afsr_write
= (pa_reg_dcd & (mm_pa[15:00] == 16'h1000) & mmstben_reg);
assign afsr_read = (pa_reg_dcd & (mm_pa[15:00] == 16'h1000) & mmreg_rd_cs) ;
wire [09:00] afsr_data_in
= {misc_in[31:24],misc_in[18:17]};
wire [09:00] afsr_in
;
// Expanded macro begin.
// cmux2(afsr_mux, 10, afsr_in, af_status, afsr_data_in, afsr_write)
function [10:1] afsr_mux ;
input [10:1] in0_fn ;
input [10:1] in1_fn ;
input select_fn ;
reg [10:1] out_fn ;
begin
case (select_fn) /* synopsys parallel_case */
1'b0: out_fn = in0_fn ;
1'b1: out_fn = in1_fn ;
default: out_fn = 65'hx;
endcase
afsr_mux = out_fn ;
end
endfunction
assign afsr_in = afsr_mux(af_status, afsr_data_in, afsr_write) ;
// Expanded macro end.
rsflop_afsr afsr_reg (afsr_out, afsr_in,
ss_clock,afar_lock,afsr_read,ss_reset);
assign afsr_err = afsr[31]; /* afsr_err is AFSR[31].*/
wire afsr_me_in
;
// Expanded macro begin.
// cmux2(afsr_me_mux, 1, afsr_me_in, af_me_bit, misc_in[19], afsr_write)
function [1:1] afsr_me_mux ;
input [1:1] in0_fn ;
input [1:1] in1_fn ;
input select_fn ;
reg [1:1] out_fn ;
begin
case (select_fn) /* synopsys parallel_case */
1'b0: out_fn = in0_fn ;
1'b1: out_fn = in1_fn ;
default: out_fn = 65'hx;
endcase
afsr_me_mux = out_fn ;
end
endfunction
assign afsr_me_in = afsr_me_mux(af_me_bit, misc_in[19], afsr_write) ;
// Expanded macro end.
rsflop afsr_me_ff (afsr_me,afsr_me_in,ss_clock,1'b0,afsr_read,ss_reset);
/*************************************************************************/
/* AFAR - Asynchronous Fault Address Register mux select decode. */
assign afar_write = (pa_reg_dcd & (mm_pa[15:00] == 16'h1004) &
mmstben_reg) ;
assign mfar_write = (pa_reg_dcd & (mm_pa[15:00] == 16'h1054) &
mmstben_reg) ;
wire mfar_acc_in
= (pa_reg_dcd & (mm_pa[15:00] == 16'h1054)) ;
wire mfar_acc
;
Mflipflop_r_1 mfar_acc_ff_1(mfar_acc,mfar_acc_in,~ss_reset,ss_clock) ;
wire r_mem_issue_req;
Mflipflop_r_1 mem_issue_req_ff_1(r_mem_issue_req,mem_issue_req,~ss_reset,ss_clock) ;
wire mfsr_read
;
wire r_mfar_lock
;
wire mfar_lock
= (mfsr[31] | r_mfar_lock | mf_perr) & ~mfsr_read;
assign hld_mfar = (~mem_issue_req | mfar_lock) & ~mfar_write ;
rsflop mfar_lock_ff (r_mfar_lock,mfar_lock,ss_clock,1'b0,mfsr_read,ss_reset);
/* */
/*****************************************************************************/
/* MFSR - Memory Fault Status Register **************************************/
/*****************************************************************************/
/* MFSR register definition */
/* */
/* +---+------+---+---+------+--+-----+---+----+---+---+------+------+-----+ */
/* |ERR| rsvd | S | CP| rsvd |ME| rsvd|ATO|PERR|MBL| C | rsvd | type | rsvd| */
/* +---+------+---+---+------+--+-----+---+----+---+---+------+------+-----+ */
/* 31 30 25 24 23 22 20 19 18 16 15 14 13 12 11 10 08 07 04 03 00 */
/* */
/* mf_status_reg */
/* +---+------+---+---+------+--+-----+---+----+---+---+------+------+-----+ */
/* | | rsvd | S | CP| rsvd | | rsvd| | |MBL| C | rsvd | type | rsvd| */
/* +---+------+---+---+------+--+-----+---+----+---+---+------+------+-----+ */
/* 07 06 05 04 03 00 */
/* */
/* mf_err_reg */
/* +---+------+---+---+------+--+-----+---+----+---+---+------+------+-----+ */
/* |ERR| rsvd | | | rsvd | | rsvd|ATO|PERR| | | rsvd | | rsvd| */
/* +---+------+---+---+------+--+-----+---+----+---+---+------+------+-----+ */
/* 03 02 01 00 */
/*****************************************************************************/
wire [03:00] mfsr_err
;
wire mfsr_me
;
wire mfsr_write
= (pa_reg_dcd & (mm_pa[15:00] == 16'h1050) & mmstben_reg) ;
assign mfsr_read = (pa_reg_dcd & (mm_pa[15:00] == 16'h1050) & mmreg_rd_cs) ;
/*** Load MFSR status each issue_req or write, but hold if error or pending **/
/*** error - perr_dcd. **/
wire mfsr_hld
= ~(r_mem_issue_req | mfsr_write) | mfsr[31] | mfsr_read |
mf_perr ;
wire mf_me_bit
= mfsr_me | (mf_perr & mfsr[31]);
/*** mf_err is loaded every cycle, and locked on mf_err ***/
wire [3:0] mf_err
= {mf_perr, mc_afx_to, dp_perr[1:0]};
/*** mf_status is loaded on every issue_req, and locked on an mf_err ***/
/*** Pipe these status bits 1-cycle to load on r_mem_issue_req ***/
wire [03:00] mf_stat_in
= {par_sbit,
~msm_sreq,
boot_mode,
par_cbit} ;
wire [03:00] mf_stat
;
Mflipflop_r_4 mf_stat_reg_4(mf_stat,mf_stat_in,~ss_reset,ss_clock) ;
/*** mm_mreq doesn't need to be piped, since it's always valid the cycle ***/
/*** after mem_issue_req. ***/
wire [07:00] mf_status
= {mf_stat, mm_mreq} ;
/*** These regs are needed to hold the mem request status for marb_sm ******/
wire [07:00] mfsr_out
; // forward
wire [3:0] mop_mreq;
MflipflopR_4 mop_mreq_ff_4(mop_mreq,mm_mreq,ss_clock,~r_mem_issue_req,ss_reset) ;
wire mop_c_hld
= ~(mem_issue_req & (r_dc_par | r_ic_par));
wire mop_c_bit;
MflipflopR_1 mop_c_bit_ff_1(mop_c_bit,par_cbit,ss_clock,mop_c_hld,ss_reset) ;
wire [07:00] mfsr_data_in
= {misc_in[24:23],misc_in[12:11],
misc_in[07:04]};
wire [03:00] mferr_data_in
= {misc_in[31],misc_in[15:13]};
wire [07:00] mfsr_in
;
// Expanded macro begin.
// cmux2(mfsr_mux, 8, mfsr_in, mf_status, mfsr_data_in, mfsr_write)
function [8:1] mfsr_mux ;
input [8:1] in0_fn ;
input [8:1] in1_fn ;
input select_fn ;
reg [8:1] out_fn ;
begin
case (select_fn) /* synopsys parallel_case */
1'b0: out_fn = in0_fn ;
1'b1: out_fn = in1_fn ;
default: out_fn = 65'hx;
endcase
mfsr_mux = out_fn ;
end
endfunction
assign mfsr_in = mfsr_mux(mf_status, mfsr_data_in, mfsr_write) ;
// Expanded macro end.
rsflop_mfsr mfsr_reg (mfsr_out,
mfsr_in,ss_clock,mfsr_hld,mfsr_read,ss_reset);
wire [03:00] mfsr_err_in
;
// Expanded macro begin.
// cmux2(mfsr_err_mux, 4, mfsr_err_in, mf_err, mferr_data_in, mfsr_write)
function [4:1] mfsr_err_mux ;
input [4:1] in0_fn ;
input [4:1] in1_fn ;
input select_fn ;
reg [4:1] out_fn ;
begin
case (select_fn) /* synopsys parallel_case */
1'b0: out_fn = in0_fn ;
1'b1: out_fn = in1_fn ;
default: out_fn = 65'hx;
endcase
mfsr_err_mux = out_fn ;
end
endfunction
assign mfsr_err_in = mfsr_err_mux(mf_err, mferr_data_in, mfsr_write) ;
// Expanded macro end.
rsflop_merr mfsr_err_reg (mfsr_err,
mfsr_err_in,
ss_clock,(mfsr[31] | mfsr_read),mfsr_read,ss_reset);
wire mfsr_me_in
;
// Expanded macro begin.
// cmux2(mfsr_me_mux, 1, mfsr_me_in, mf_me_bit, misc_in[19], mfsr_write)
function [1:1] mfsr_me_mux ;
input [1:1] in0_fn ;
input [1:1] in1_fn ;
input select_fn ;
reg [1:1] out_fn ;
begin
case (select_fn) /* synopsys parallel_case */
1'b0: out_fn = in0_fn ;
1'b1: out_fn = in1_fn ;
default: out_fn = 65'hx;
endcase
mfsr_me_mux = out_fn ;
end
endfunction
assign mfsr_me_in = mfsr_me_mux(mf_me_bit, misc_in[19], mfsr_write) ;
// Expanded macro end.
rsflop mfsr_me_ff (mfsr_me,mfsr_me_in,ss_clock,1'b0,mfsr_read,ss_reset);
assign mfsr = {mfsr_err[3],6'b0,mfsr_out[7:6],3'b0,mfsr_me,3'b0,
mfsr_err[2:0],mfsr_out[5:4],3'b0,mfsr_out[3:0],4'b0};
/* */
/*****************************************************************************/
/** Register READ to MDATA bus multiplexing. **/
/*****************************************************************************/
wire [2:0] sscr_rd_out
;
wire [2:0] sscr_rd_out1
;
wire [1:0] sscr_rd_sel
= mm_pa[03:02];
// Expanded macro begin.
// cmux4(sscr_rd_mux1, 4, sscr_rd_out1, sscr0_out, sscr1_out, sscr2_out, sscr3_out, sscr_rd_sel)
function [4:1] sscr_rd_mux1 ;
input [4:1] in0_fn ;
input [4:1] in1_fn ;
input [4:1] in2_fn ;
input [4:1] in3_fn ;
input [1:0] select_fn ;
reg [4:1] out_fn ;
begin
case (select_fn) /* synopsys parallel_case */
2'b00: out_fn = in0_fn ;
2'b01: out_fn = in1_fn ;
2'b10: out_fn = in2_fn ;
2'b11: out_fn = in3_fn ;
default: out_fn = 65'hx;
endcase
sscr_rd_mux1 = out_fn ;
end
endfunction
assign sscr_rd_out1 = sscr_rd_mux1( sscr0_out, sscr1_out, sscr2_out, sscr3_out, sscr_rd_sel) ;
// Expanded macro end.
// Expanded macro begin.
// cmux2(sscr_rd_mux, 4, sscr_rd_out, sscr_rd_out1, sscr4_out, mm_pa[5])
function [4:1] sscr_rd_mux ;
input [4:1] in0_fn ;
input [4:1] in1_fn ;
input select_fn ;
reg [4:1] out_fn ;
begin
case (select_fn) /* synopsys parallel_case */
1'b0: out_fn = in0_fn ;
1'b1: out_fn = in1_fn ;
default: out_fn = 65'hx;
endcase
sscr_rd_mux = out_fn ;
end
endfunction
assign sscr_rd_out = sscr_rd_mux( sscr_rd_out1, sscr4_out, mm_pa[5]) ;
// Expanded macro end.
/*****************************************************************************/
/** Generate output decodes **/
// change these to switch at pipe move time.
// assign mmu_bypass = ((((~mmu_cr[0] | ~mmu_cr_reg[0]) | // MMU enable
// (mmu_cr[15] & mmu_cr_reg[10]) | // AC enable
assign mmu_bypass = (((~mmu_cr[0] | // MMU enable
mmu_cr[15] | // AC enable
boot_mode | bypass_mmu_asi |
ic_par_state | dc_par_state) & ~io_op) |
(io_op & (~io_cr[0] | io_mmu_bp | sb_write)));
// change these to switch at pipe move time.
// assign wr_bypass = (~mmu_cr[0] | ~mmu_cr_reg[0]) | // MMU enable
// (mmu_cr[15] & mmu_cr_reg[10]) ; // AC enable
assign wr_bypass = ~mmu_cr[0] | // MMU enable
mmu_cr[15] ; // AC enable
wire tlb_cmp_cyc
= c_en & ~(mmu_asi_op | tlb_flush) ;
wire r_tlb_compare;
Mflipflop_r_1 tlb_compare_ff_1(r_tlb_compare,tlb_cmp_cyc,~ss_reset,ss_clock) ;
assign tlb_miss = (~mmu_bypass & ~r_tlb_compare) |
(tlb_miss_raw & ~mmu_bypass & r_tlb_compare);
assign tlb_m_miss = (~mmu_bypass & ~r_tlb_compare) |
(m_miss & ~mmu_bypass & r_tlb_compare);
assign tlb_err = (tb_error & ~mmu_bypass & r_tlb_compare & ~tlb_miss_raw);
/*****************************************************************************/
/*** tlb_hit means no exceptions and modified bit ok and ~tlb_miss ***********/
/*** This is NOT the inverse of tlb_miss !!! ***********/
assign tlb_hit = mmu_bypass | (acc_ok & ~mmu_bypass & r_tlb_compare);
/** **/
/*****************************************************************************/
/************** ASI read access muxing - output on to mdata bus **************/
/*****************************************************************************/
wire probe_err;
wire probe_err_in
= (tw_prb_err | (probe & r_tlb_walk_perr) |
probe_err) & ~(mmu_daten & ~mm_dstat_avail);
Mflipflop_r_1 probe_err_ff_1(probe_err,probe_err_in,~ss_reset,ss_clock) ;
wire probe_inv
;
wire probe_inv_in
= (probe_invalid | (probe & r_tlb_walk_perr) |
tw_prb_err | probe_inv) & ~mmu_daten;
Mflipflop_r_1 probe_inv_ff_1(probe_inv,probe_inv_in,~ss_reset,ss_clock) ;
/*****************************************************************************/
/***** ASI read mux select decode logic *************************************/
/*****************************************************************************/
/** Mux select decode for final MMU read mux **/
wire rd_mmu_sel
= (sel_cache_stat) |
((asi_dcd3 & ~probe_err) | asi_dcd6 | tw_write |
(asi_dcd4 & r_dva_12_8[8] & ~r_dva_12_8[9]) |
(asi_dcd4 & r_dva_12_8[10]) |
((~(asi_dcd4 | asi_dcd6 | (asi_dcd3 & probe_err))) &
((mm_pa[2] & ~(mm_pa[6] ^ mm_pa[4]) & ~mm_pa[13]) |
(mm_pa[13] & mm_pa[4]))));
/*** A separate select is needed for bit [01] to support ***/
/*** probes of invalid PTEs ***/
wire rd_mmu_sel1
= (sel_cache_stat) |
((asi_dcd3 & ~(probe_err | probe_inv)) | asi_dcd6 |
tw_write |
(asi_dcd4 & r_dva_12_8[8] & ~r_dva_12_8[9]) |
(asi_dcd4 & r_dva_12_8[10]) |
((~(asi_dcd4 | asi_dcd6 | (asi_dcd3 &
(probe_err |probe_inv)))) &
((mm_pa[2] & ~(mm_pa[6] ^ mm_pa[4]) & ~mm_pa[13]) |
(mm_pa[13] & mm_pa[4]))));
/*** TLB read Select - use bits 8 & 9 for ram sel ****************************/
wire tlb_read_sel
= asi_dcd6 & ~r_dva_12_8[8] & ~r_dva_12_8[9];
/** Mux select decode for Misc. registers ************************************/
/** dp_mux1_sel[4] - TLB Output reg (data) **/
/** dp_mux1_sel[3] - IBAR (default) **/
/** dp_mux1_sel[2] - MFAR data **/
/** dp_mux1_sel[1] - SFAR data **/
/** dp_mux1_sel[0] - CTPR data **/
/** ss_scan_mode for mux control during scan, only dp_mux1_sel[0] on **/
assign dp_mux1_sel = {((probe_done | tlb_read_sel) & ~ss_scan_mode),
(~(asi_dcd4 | mfar_acc | tlb_read_sel | probe_done) &
~ss_scan_mode),
(mfar_acc & ~ss_scan_mode),
(asi_dcd4 & r_dva_12_8[10] & ~ss_scan_mode),
((asi_dcd4 & ~r_dva_12_8[10]) | ss_scan_mode) };
/** Mux select decode for Physically addressed registers *********************/
/** pamux_rd_sel[4] - dp_mux1 data (TLB read data) **/
/** pamux_rd_sel[3] - Control space regs (brkpt + AFAR) **/
/** pamux_rd_sel[2] - table walk or probe **/
/** pamux_rd_sel[1] - TLB read tag **/
/** pamux_rd_sel[0] - cache stat data (default) **/
/** ss_scan_mode for mux control during scan, only pamux_rd_sel[0] on **/
assign pamux_rd_sel = {
(~((pa_reg_dcd & mm_pa[12] & ~tw_write & ~mfar_acc) |
(tw_write | (probe_done & ~mm_dstat_avail & ~cam_reg_hld)) |
(asi_dcd6 & r_dva_12_8[8] & ~tw_write & ~sel_cache_stat) |
(sel_cache_stat & ~(pa_reg_dcd | tw_write))) & ~ss_scan_mode),
(pa_reg_dcd & mm_pa[12] & ~tw_write & ~mfar_acc & ~ss_scan_mode),
((tw_write | (probe_done & ~mm_dstat_avail & ~cam_reg_hld)) & ~ss_scan_mode),
(asi_dcd6 & r_dva_12_8[8] & ~tw_write & ~sel_cache_stat & ~ss_scan_mode),
((sel_cache_stat & ~(pa_reg_dcd | tw_write)) | ss_scan_mode)};
/** Mux select decode for ASI=4 DVA addressed registers *********************/
/** dva_regs_sel[3] - ASI = 0x3 probe data on PTE error **/
/** dva_regs_sel[2] - ASI != 0x4 | 0x3 (default) mmu_paregs **/
/** dva_regs_sel[1] - ASI = 0x4 (SFSR or PCR) **/
/** dva_regs_sel[0] - ASI = 0x4 & DVA[12:8] = 10 or 02 (TRCR or CXR) **/
wire [3:0] dva_regs_sel
= {asi_dcd3,
(~(asi_dcd3 | asi_dcd4)),
(asi_dcd4 & (r_dva_12_8[8] |
(~r_dva_12_8[12] & ~r_dva_12_8[9]))),
(asi_dcd4 & ~r_dva_12_8[8] &
(r_dva_12_8[12] | r_dva_12_8[9]))};
/** Mux select decode for ASI=4 DVA addressed registers *********************/
/** pareg_sel[4] - MFSR 1000 1050 **/
/** pareg_sel[3] - SSCR regs 1000 101X or 1000 102X **/
/** pareg_sel[2] - AFSR 1000 1000 **/
/** pareg_sel[1] - MID /perf cntr 1000 2XXX or 1000 3XXX **/
/** pareg_sel[0] - default (IO_CR) 1000 0000 **/
wire [4:0] pareg_sel
= {(~mm_pa[13] & mm_pa[12] & mm_pa[6]),
(~mm_pa[13] & mm_pa[12] & ~mm_pa[6] &
(mm_pa[4] | mm_pa[5])),
(~mm_pa[13] & mm_pa[12] & ~mm_pa[6] &
~(mm_pa[4] | mm_pa[5])),
(mm_pa[13]),
~(mm_pa[12] | mm_pa[13])};
/* */
/*****************************************************************************/
/***** ASI read CMUX logic ***************************************************/
/*****************************************************************************/
/*** 1st level register read muxes ***/
wire [31:00] sfsr_pad
= {15'b0, sfsr[14], 1'b0, sfsr[13:12], 1'b0,
sfsr[11:00]};
wire [31:00] rd_mux1_out
;
// Expanded macro begin.
// cmux2(rd_mux1, 32, rd_mux1_out, mmu_cr, sfsr_pad, r_dva_12_8[8])
function [32:1] rd_mux1 ;
input [32:1] in0_fn ;
input [32:1] in1_fn ;
input select_fn ;
reg [32:1] out_fn ;
begin
case (select_fn) /* synopsys parallel_case */
1'b0: out_fn = in0_fn ;
1'b1: out_fn = in1_fn ;
default: out_fn = 65'hx;
endcase
rd_mux1 = out_fn ;
end
endfunction
assign rd_mux1_out = rd_mux1( mmu_cr, sfsr_pad, r_dva_12_8[8]) ;
// Expanded macro end.
wire [24:0] cxr_rcr
= {17'b0, cxr};
wire [24:00] rd_mux2_out
;
// Expanded macro begin.
// cmux2(rd_mux2, 25, rd_mux2_out, cxr_rcr, tlb_rcr, r_dva_12_8[12])
function [25:1] rd_mux2 ;
input [25:1] in0_fn ;
input [25:1] in1_fn ;
input select_fn ;
reg [25:1] out_fn ;
begin
case (select_fn) /* synopsys parallel_case */
1'b0: out_fn = in0_fn ;
1'b1: out_fn = in1_fn ;
default: out_fn = 65'hx;
endcase
rd_mux2 = out_fn ;
end
endfunction
assign rd_mux2_out = rd_mux2( cxr_rcr, tlb_rcr, r_dva_12_8[12]) ;
// Expanded macro end.
/*** Read muxes for AFX Queue control and status regs *****/
/*****************************************************************************/
/* AFX Queue level (PA = 0x1000 6000) */
/* 1-bit reg that determines when processor AFX reads can */
/* be issued. AFX Queue level will postpone AFX read request */
/* when it is less than the number of entries in the AFX Queue. */
/* */
/* +-------------------------------------------------------------------+---+ */
/* | reserved (reads as 0) |LVL| */
/* +-------------------------------------------------------------------+---+ */
/* 31 01 00 */
/* */
/*****************************************************************************/
/*****************************************************************************/
/* AFX Queue status (PA = 0x1000 7000) */
/* 3-bit READ-ONLY register that reflects the AFX Queue status. */
/* this should contain a value between 0x0 and 0x4. */
/* */
/* +-------------------------------------------------------------+---------+ */
/* | reserved (reads as 0) | Q LVL | */
/* +-------------------------------------------------------------+---------+ */
/* 31 03 02 00 */
/* */
/*****************************************************************************/
wire [31:0] afx_stat
= {28'b0, r_p_reply_dec} ;
wire [31:0] afx_qlvl_pad
= {30'b0, afx_qlvl} ;
/***** Read Physically Addressed register mux (4:1) *****/
/**** this mux is part of random logic, so I used encoded selects **/
wire [26:00] perf_mux_out
; // forward
wire [31:00] perf_enbls
= {5'b0, perf_mux_out} ;
wire [31:00] pamux1_out
;
wire [1:0] pamux1_sel
= {mm_pa[14], mm_pa[12]} ;
// Expanded macro begin.
// cmux4(pamux1, 32, pamux1_out, mid, /* PA = 0x1000 2000 */ perf_enbls, /* PA = 0x1000 30XX */ afx_qlvl_pad, /* PA = 0x1000 6000 */ afx_stat, /* PA = 0x1000 7000 */ pamux1_sel)
function [32:1] pamux1 ;
input [32:1] in0_fn ;
input [32:1] in1_fn ;
input [32:1] in2_fn ;
input [32:1] in3_fn ;
input [1:0] select_fn ;
reg [32:1] out_fn ;
begin
case (select_fn) /* synopsys parallel_case */
2'b00: out_fn = in0_fn ;
2'b01: out_fn = in1_fn ;
2'b10: out_fn = in2_fn ;
2'b11: out_fn = in3_fn ;
default: out_fn = 65'hx;
endcase
pamux1 = out_fn ;
end
endfunction
assign pamux1_out = pamux1( mid, /* PA = 0x1000 2000 */ perf_enbls, /* PA = 0x1000 30XX */ afx_qlvl_pad, /* PA = 0x1000 6000 */ afx_stat, /* PA = 0x1000 7000 */ pamux1_sel) ;
// Expanded macro end.
wire [31:00] sscr_pad
= {15'b0,sscr_rd_out[2],14'b0,sscr_rd_out[1:0]};
wire [31:00] pa_regs_mux
;
// Expanded macro begin.
// cmux5dnm(pa_regs_mux, 32, pa_regs_mux, io_cr, pareg_sel[0], pamux1_out, pareg_sel[1], afsr, pareg_sel[2], sscr_pad, pareg_sel[3], mfsr, pareg_sel[4])
function [32:1] fn_pa_regs_mux ;
input [32:1] in0_fn ;
input s0_fn ;
input [32:1] in1_fn ;
input s1_fn ;
input [32:1] in2_fn ;
input s2_fn ;
input [32:1] in3_fn ;
input s3_fn ;
input [32:1] in4_fn ;
input s4_fn ;
reg [32:1] out_fn ;
begin
case ({pareg_sel[4], pareg_sel[3], pareg_sel[2], pareg_sel[1], pareg_sel[0]}) /* synopsys parallel_case */
5'b00001: out_fn = in0_fn ;
5'b00010: out_fn = in1_fn ;
5'b00100: out_fn = in2_fn ;
5'b01000: out_fn = in3_fn ;
5'b10000: out_fn = in4_fn ;
default: out_fn = 65'hx;
endcase
fn_pa_regs_mux = out_fn ;
end
endfunction
assign pa_regs_mux = fn_pa_regs_mux( io_cr, pareg_sel[0], pamux1_out, pareg_sel[1], afsr, pareg_sel[2], sscr_pad, pareg_sel[3], mfsr, pareg_sel[4]) ;
// Expanded macro end.
/***** Read Virtually Addressed register mux (4:1) *****/
wire [31:00] rd_mux2_pad
= {7'b0,rd_mux2_out};
wire [31:00] zero_rd
= {32'b0};
wire [31:00] dva_regs_out
;
// Expanded macro begin.
// cmux4dnm(dva_regs_mux, 32, dva_regs_out, rd_mux2_pad, dva_regs_sel[0], rd_mux1_out, dva_regs_sel[1], pa_regs_mux, dva_regs_sel[2], zero_rd, dva_regs_sel[3])
function [32:1] dva_regs_mux ;
input [32:1] in0_fn ;
input s0_fn ;
input [32:1] in1_fn ;
input s1_fn ;
input [32:1] in2_fn ;
input s2_fn ;
input [32:1] in3_fn ;
input s3_fn ;
reg [32:1] out_fn ;
begin
case ({dva_regs_sel[3], dva_regs_sel[2], dva_regs_sel[1], dva_regs_sel[0]}) /* synopsys parallel_case */
4'b0001: out_fn = in0_fn;
4'b0010: out_fn = in1_fn;
4'b0100: out_fn = in2_fn;
4'b1000: out_fn = in3_fn;
default: out_fn = 65'hx;
endcase
dva_regs_mux = out_fn ;
end
endfunction
assign dva_regs_out = dva_regs_mux( rd_mux2_pad, dva_regs_sel[0], rd_mux1_out, dva_regs_sel[1], pa_regs_mux, dva_regs_sel[2], zero_rd, dva_regs_sel[3]) ;
// Expanded macro end.
/***** Send cache-ability status for both the cycle of the request, ***/
/***** and the following cycle. ***/
wire issue_req
= mem_issue_req | io_issue_req ;
wire r_issue_req
;
Mflipflop_r_1 issue_req_ff_1(r_issue_req,issue_req,~ss_reset,ss_clock) ;
wire cache_stat
= par_cbit & ~mmu_asi_op ;
wire r_cache_stat
;
Mflipflop_r_1 cache_stat_ff_1(r_cache_stat,cache_stat,~ss_reset,ss_clock) ;
assign mm_cache_stat = r_issue_req ? r_cache_stat : cache_stat ;
/***** Mux for cxr status bits [11] and [3:0] ***************/
wire[7:0] cxr_stat_11_4
;
// Expanded macro begin.
// cmux2(cxr_stat, 8, cxr_stat_11_4, pa_mux_rd[11:4], cxr, sel_cache_stat)
function [8:1] cxr_stat ;
input [8:1] in0_fn ;
input [8:1] in1_fn ;
input select_fn ;
reg [8:1] out_fn ;
begin
case (select_fn) /* synopsys parallel_case */
1'b0: out_fn = in0_fn ;
1'b1: out_fn = in1_fn ;
default: out_fn = 65'hx;
endcase
cxr_stat = out_fn ;
end
endfunction
assign cxr_stat_11_4 = cxr_stat( pa_mux_rd[11:4], cxr, sel_cache_stat) ;
// Expanded macro end.
/*** the access permission field is either the TLB acc field, or ********/
/*** when in AC mode, the top 3-bit of the context reg. ********/
/*** This is to allow diags to test all tag patterns in AC mode. *****/
/*** separate wire assignment, so value can be forced in mode files *****/
/*** For AC mode, use diagnostic ACC field from the Context reg. *****/
// move AC enable to switch on pipe move
//wire [2:0] cache_stat_acc = (~mmu_en_e | (mmu_cr[15] & mmu_cr_reg[10])) ?
wire [2:0] cache_stat_acc
= (~mmu_en_e | mmu_cr[15] ) ?
3'b011 : tlb_acc_x ;
wire [2:0] cache_stat_2_0
;
// Expanded macro begin.
// cmux2(cache_stat, 3, cache_stat_2_0, pa_mux_rd[3:1], cache_stat_acc, sel_cache_stat)
function [3:1] fn_cache_stat ;
input [3:1] in0_fn ;
input [3:1] in1_fn ;
input select_fn ;
reg [3:1] out_fn ;
begin
case (select_fn) /* synopsys parallel_case */
1'b0: out_fn = in0_fn ;
1'b1: out_fn = in1_fn ;
default: out_fn = 65'hx;
endcase
fn_cache_stat = out_fn ;
end
endfunction
assign cache_stat_2_0 = fn_cache_stat( pa_mux_rd[3:1], cache_stat_acc, sel_cache_stat) ;
// Expanded macro end.
wire [4:0] pa_mux_out_h
;
// Expanded macro begin.
// cmux2(pa_out_hi_bits, 5, pa_mux_out_h, pa_mux_rd[31:27], 5'b0, tw_par)
function [5:1] pa_out_hi_bits ;
input [5:1] in0_fn ;
input [5:1] in1_fn ;
input select_fn ;
reg [5:1] out_fn ;
begin
case (select_fn) /* synopsys parallel_case */
1'b0: out_fn = in0_fn ;
1'b1: out_fn = in1_fn ;
default: out_fn = 65'hx;
endcase
pa_out_hi_bits = out_fn ;
end
endfunction
assign pa_mux_out_h = pa_out_hi_bits( pa_mux_rd[31:27], 5'b0, tw_par) ;
// Expanded macro end.
wire [31:0] pa_mux_rd1
= {pa_mux_out_h,pa_mux_rd[26:12],
cxr_stat_11_4, cache_stat_2_0, pa_mux_rd[0] } ;
/***** Read MMU data mux (2:1) that combines all read MMU data *****/
wire [29:00] rd_mmu_data2
;
// Expanded macro begin.
// cmux2(rd_mmu_mux, 30, rd_mmu_data2, dva_regs_out[31:02], pa_mux_rd1[31:02], rd_mmu_sel)
function [30:1] rd_mmu_mux ;
input [30:1] in0_fn ;
input [30:1] in1_fn ;
input select_fn ;
reg [30:1] out_fn ;
begin
case (select_fn) /* synopsys parallel_case */
1'b0: out_fn = in0_fn ;
1'b1: out_fn = in1_fn ;
default: out_fn = 65'hx;
endcase
rd_mmu_mux = out_fn ;
end
endfunction
assign rd_mmu_data2 = rd_mmu_mux( dva_regs_out[31:02], pa_mux_rd1[31:02], rd_mmu_sel) ;
// Expanded macro end.
wire [1:0] rd_mmu_data1
;
// Expanded macro begin.
// cmux2(rd_mmu_mux1, 2, rd_mmu_data1, dva_regs_out[1:0], pa_mux_rd1[1:0], rd_mmu_sel1)
function [2:1] rd_mmu_mux1 ;
input [2:1] in0_fn ;
input [2:1] in1_fn ;
input select_fn ;
reg [2:1] out_fn ;
begin
case (select_fn) /* synopsys parallel_case */
1'b0: out_fn = in0_fn ;
1'b1: out_fn = in1_fn ;
default: out_fn = 65'hx;
endcase
rd_mmu_mux1 = out_fn ;
end
endfunction
assign rd_mmu_data1 = rd_mmu_mux1( dva_regs_out[1:0], pa_mux_rd1[1:0], rd_mmu_sel1) ;
// Expanded macro end.
wire [31:00] rd_mmu_data
= {rd_mmu_data2, rd_mmu_data1};
/*** Register all read data before driving onto misc bus. **********/
wire [31:00] r_mmu_data
;
Mflipflop_r_32 mmu_data_reg_32(r_mmu_data,rd_mmu_data,~ss_reset,ss_clock) ;
/*************************************************************************/
/*** TRI-STATE driver for the misc bus ***********************************/
This page: |
Created: | Thu Aug 19 12:02:52 1999 |
| From: |
../../../sparc_v8/ssparc/mmu/m_mmu_cntl/rtl/rl_mmu_regs.v
|