if (ss_reset)
begin
mm_rom_module_speed <= #1 4'hf ;
// mm_rom_module_speed <= #1 bm_sel[1] ? 4'h0 : 4'hf ; back to 4'hf
end
else if (~hld_mid)
begin
mm_rom_module_speed <= #1 misc_in[7:4] ;
end
wire [31:00] mid
= {10'h000,mid_out,4'h0,mm_go_standby,w_sp_sel[2:0],mm_rom_module_speed[3:0],4'h8};
// fix the line below, had 33 bits defined for mid
// wire [31:00] mid = {11'b0,mid_out,4'b0,mm_go_standby,w_sp_sel[2:0],mm_rom_module_speed[3:0],4'h8};
//-----------------------------------
// wire [31:00] mid = {11'b0,mid_out,16'h0008};
assign mm_sbae = mid_out;
/*****************************************************************************/
/* IO Flush ALL register */
/* No data register exists for this address (only command) */
wire flush_ioall_in
= pa_reg_dcd & (mm_pa[15:00] == 16'h0014);
wire flush_ioall_dcd
;
MflipflopR_1 flush_ioall_dcd_ff_1(flush_ioall_dcd,flush_ioall_in,ss_clock, 1'b0,ss_reset) ;
assign flush_ioall = flush_ioall_dcd & mmstben_reg;
/*****************************************************************************/
/* IO PTE Flush register */
/* No data register exists for this address (only command) */
wire flush_io_dcd_in
= pa_reg_dcd & (mm_pa[15:00] == 16'h0018);
wire flush_iopte_dcd
;
MflipflopR_1 flush_iopte_dcd_ff_1(flush_iopte_dcd,flush_io_dcd_in,ss_clock, 1'b0,ss_reset) ;
assign flush_iopte = flush_iopte_dcd & mmstben_reg;
/*****************************************************************************/
/* IO Control Register (currently 32-bits). */
/* */
/* +------+------+----------------------------------------+-------+----+---+ */
/* | IMPL | VER | reserved | Range |rsvd| ME| */
/* +------+------+----------------------------------------+-------+----+---+ */
/* 31 28 27 24 23 05 04 02 01 00 */
/* */
/*****************************************************************************/
wire hld_io_cr
= ~(pa_reg_dcd & (mm_pa[15:00] == 16'h0000) & mmstben_reg);
wire [03:00] io_cr_in
= {misc_in[04:02],misc_in[0]}; /* rename inputs */
wire [03:00] io_cr_out
;
MflipflopR_4 io_cr_4( io_cr_out, io_cr_in, /* data loaded from the MDATA bus*/ ss_clock,hld_io_cr,ss_reset) ; /* load enable for IO_CR*/
wire [31:00] io_cr
= {4'h0,4'h4,19'b0,io_cr_out[3:1],1'b0,io_cr_out[0]};
/** IMPL = 0, VER = 4 (same as PSR and PCR) **/
assign io_range = io_cr[4:2]; /* output IO range field */
assign io_mmu_en = io_cr[0];
/* */
/*****************************************************************************/
/* SSCR0 - Sbus Status/Control Register for Sbus_ID = 0. (PA = 0x10001010) */
/* */
/* +-------------------------------+----+-------------------------+----+---+ */
/* | reserved |SA30| reserved | BA8| BY| */
/* +-------------------------------+----+-------------------------+----+---+ */
/* 31 17 16 15 02 01 00 */
/* */
/*****************************************************************************/
wire hld_sscr0
= ~(pa_reg_dcd & (mm_pa[15:00] == 16'h1010) & mmstben_reg);
wire [2:0] sscr0_in
= {misc_in[16], misc_in[1:0]}; /* rename inputs */
wire [2:0] sscr0_out
;
MflipflopR_3 sscr0_3( sscr0_out, sscr0_in, /* data loaded from the MDATA bus*/ ss_clock,hld_sscr0,ss_reset) ; /* load enable for SSCR0*/
/*****************************************************************************/
/* SSCR1 - Sbus Status/Control Register for Sbus_ID = 1. (PA = 0x10001014) */
/* */
/* +-------------------------------+----+-------------------------+----+---+ */
/* | reserved |SA30| reserved | BA8| BY| */
/* +-------------------------------+----+-------------------------+----+---+ */
/* 31 17 16 15 02 01 00 */
/* */
/*****************************************************************************/
wire hld_sscr1
= ~(pa_reg_dcd & (mm_pa[15:00] == 16'h1014) & mmstben_reg);
wire [2:0] sscr1_in
= {misc_in[16], misc_in[1:0]}; /* rename inputs */
wire [2:0] sscr1_out
;
MflipflopR_3 sscr1_3( sscr1_out, sscr1_in, /* data loaded from the MDATA bus*/ ss_clock,hld_sscr1,ss_reset) ; /* load enable for SSCR1*/
/*****************************************************************************/
/* SSCR2 - Sbus Status/Control Register for Sbus_ID = 2. (PA = 0x10001018) */
/* */
/* +-------------------------------+----+-------------------------+----+---+ */
/* | reserved |SA30| reserved | BA8| BY| */
/* +-------------------------------+----+-------------------------+----+---+ */
/* 31 17 16 15 02 01 00 */
/* */
/*****************************************************************************/
wire hld_sscr2
= ~(pa_reg_dcd & (mm_pa[15:00] == 16'h1018) & mmstben_reg);
wire [2:0] sscr2_in
= {misc_in[16], misc_in[1:0]}; /* rename inputs */
wire [2:0] sscr2_out
;
MflipflopR_3 sscr2_3( sscr2_out, sscr2_in, /* data loaded from the MDATA bus*/ ss_clock,hld_sscr2,ss_reset) ; /* load enable for SSCR2*/
/*****************************************************************************/
/* SSCR3 - Sbus Status/Control Register for Sbus_ID = 3. (PA = 0x1000101c) */
/* */
/* +-------------------------------+----+-------------------------+----+---+ */
/* | reserved |SA30| reserved | BA8| BY| */
/* +-------------------------------+----+-------------------------+----+---+ */
/* 31 17 16 15 02 01 00 */
/* */
/*****************************************************************************/
wire hld_sscr3
= ~(pa_reg_dcd & (mm_pa[15:00] == 16'h101c) & mmstben_reg);
wire [2:0] sscr3_in
= {misc_in[16], misc_in[1:0]}; /* rename inputs */
wire [2:0] sscr3_out
;
MflipflopR_3 sscr3_3( sscr3_out, sscr3_in, /* data loaded from the MDATA bus*/ ss_clock,hld_sscr3,ss_reset) ; /* load enable for SSCR3*/
/*****************************************************************************/
/* SSCR4 - Sbus Status/Control Register for Sbus_ID = 4. (PA = 0x10001020) */
/* */
/* +-------------------------------+----+-------------------------+----+---+ */
/* | reserved |SA30| reserved | BA8| BY| */
/* +-------------------------------+----+-------------------------+----+---+ */
/* 31 17 16 15 02 01 00 */
/* */
/*****************************************************************************/
wire hld_sscr4
= ~(pa_reg_dcd & (mm_pa[15:00] == 16'h1020) & mmstben_reg);
wire [2:0] sscr4_in
= {misc_in[16], misc_in[1:0]}; /* rename inputs */
wire [2:0] sscr4_out
;
MflipflopR_3 sscr4_3( sscr4_out, sscr4_in, /* data loaded from the MDATA bus*/ ss_clock,hld_sscr4,ss_reset) ; /* load enable for SSCR4*/
assign mm_sscr_ba8 = {sscr4_out[1],sscr3_out[1],sscr2_out[1],
sscr1_out[1],sscr0_out[1]};
/*************************************************************************/
/* IO address Register for virtual address error checking. ***/
wire [31:24] r_ioadr
;
Mflipflop_8 ioadr_reg_8(r_ioadr,sb_ioa,ss_clock,sb_va_val_l) ;
/*************************************************************************/
/*** Load/Hold enables for datapath registers ***/
assign hld_ibar = ~(pa_reg_dcd & (mm_pa[15:00] == 16'h0004) &
mmstben_reg) ;
assign vaf_en_hld = ~(pa_reg_dcd & (mm_pa[15:00] == 16'h3018) &
mmstben_reg) ;
assign va_bp_hld = ~(pa_reg_dcd & (mm_pa[15:00] == 16'h301c) &
mmstben_reg) ;
assign ld_pcntr_a = (pa_reg_dcd & (mm_pa[15:00] == 16'h3010) &
mmstben_reg) ;
assign ld_pcntr_b = (pa_reg_dcd & (mm_pa[15:00] == 16'h3014) &
mmstben_reg) ;
assign sel_brkpt_mux = (pa_reg_dcd & (mm_pa[15:12] == 4'h3)) ;
wire afsr_err
;
wire afsr_read
;
wire r_afar_lock
;
wire afar_lock
= (afsr_err | r_afar_lock) & ~afsr_read;
assign hld_afar = (~io_issue_req | afar_lock) &
~(pa_reg_dcd & (mm_pa[15:00] == 16'h1004) &
mmstben_reg) ;
rsflop afar_lock_ff (r_afar_lock,afar_lock,ss_clock,1'b0,afsr_read,ss_reset);
/*************************************************************************/
/*** Some SSCR muxing for bit[30] of the PA muxing ***********************/
/* SSCR mux (4:1) provides SSCRn[16] according to Sbus slot ID. */
wire io_mmu_bp30
;
wire io_bp_enbl
;
wire sscr0_3_out3
;
wire sscr0_3_out0
;
// Expanded macro begin.
// cmux4(sscr_mux1, 1, sscr0_3_out3, sscr0_out[2], /* SSCR0[16] - PA[30] for SBus slot 0.*/ sscr1_out[2], /* SSCR1[16] - PA[30] for SBus slot 1.*/ sscr2_out[2], /* SSCR2[16] - PA[30] for SBus slot 2.*/ sscr3_out[2], /* SSCR3[16] - PA[30] for SBus slot 3.*/ sb_sbslot[1:0])
function [ 1:1] sscr_mux1 ;
input [ 1:1] in0_fn ;
input [ 1:1] in1_fn ;
input [ 1:1] in2_fn ;
input [ 1:1] in3_fn ;
input [1:0] select_fn ;
reg [ 1: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_mux1 = out_fn ;
end
endfunction
assign sscr0_3_out3 = sscr_mux1( sscr0_out[2], /* SSCR0[16] - PA[30] for SBus slot 0.*/ sscr1_out[2], /* SSCR1[16] - PA[30] for SBus slot 1.*/ sscr2_out[2], /* SSCR2[16] - PA[30] for SBus slot 2.*/ sscr3_out[2], /* SSCR3[16] - PA[30] for SBus slot 3.*/ sb_sbslot[1:0]) ;
// Expanded macro end.
/* select from SBus slot ID.*/
// Expanded macro begin.
// cmux2(sscr_mux, 1, io_mmu_bp30, sscr0_3_out3, sscr4_out[2], /* SSCR3[16] - PA[30] for SBus slot 3.*/ sb_sbslot[2])
function [ 1:1] sscr_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
sscr_mux = out_fn ;
end
endfunction
assign io_mmu_bp30 = sscr_mux( sscr0_3_out3, sscr4_out[2], /* SSCR3[16] - PA[30] for SBus slot 3.*/ sb_sbslot[2]) ;
// Expanded macro end.
/* select from SBus slot ID.*/
// Expanded macro begin.
// cmux4(sscr_bpmux1, 1, sscr0_3_out0, sscr0_out[0], /* SSCR0[0] - IO bypass for SBus slot 0.*/ sscr1_out[0], /* SSCR1[0] - IO bypass for SBus slot 1.*/ sscr2_out[0], /* SSCR2[0] - IO bypass for SBus slot 2.*/ sscr3_out[0], /* SSCR3[0] - IO bypass for SBus slot 3.*/ sb_sbslot[1:0])
function [ 1:1] sscr_bpmux1 ;
input [ 1:1] in0_fn ;
input [ 1:1] in1_fn ;
input [ 1:1] in2_fn ;
input [ 1:1] in3_fn ;
input [1:0] select_fn ;
reg [ 1: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_bpmux1 = out_fn ;
end
endfunction
assign sscr0_3_out0 = sscr_bpmux1( sscr0_out[0], /* SSCR0[0] - IO bypass for SBus slot 0.*/ sscr1_out[0], /* SSCR1[0] - IO bypass for SBus slot 1.*/ sscr2_out[0], /* SSCR2[0] - IO bypass for SBus slot 2.*/ sscr3_out[0], /* SSCR3[0] - IO bypass for SBus slot 3.*/ sb_sbslot[1:0]) ;
// Expanded macro end.
/* select from SBus slot ID.*/
// Expanded macro begin.
// cmux2(sscr_bpmux, 1, io_bp_enbl, sscr0_3_out0, sscr4_out[0], /* SSCR4[0] - IO bypass for SBus slot 4.*/ sb_sbslot[2])
function [ 1:1] sscr_bpmux ;
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
sscr_bpmux = out_fn ;
end
endfunction
assign io_bp_enbl = sscr_bpmux( sscr0_3_out0, sscr4_out[0], /* SSCR4[0] - IO bypass for SBus slot 4.*/ sb_sbslot[2]) ;
// Expanded macro end.
/* select from SBus slot ID.*/
/* BOOT MODE mux (2:1) provides both IO_MMU Bypass[30] and Boot Mode[30]. */
/** CMUX2(boot_30, 1, boot_out_30, **/
/** 1'b1, force "1" if in BOOT MODE **/
/** io_mmu_bp30, SSCRn[16] according to Sbus slot ID*/
/** sel_io_bp) **/
// modified to make the old sbus boot address bit 30 turn off so that
// we generate an address which will be detected by the pcic and
// all boot from the pcic.
// assign boot_out_30 = (~io_mmu_bp | (io_mmu_bp & io_mmu_bp30));
assign boot_out_30 = io_mmu_bp & io_mmu_bp30;
/*************************************************************************/
/* */
/*************************************************************************/
/* SFSR - Synchronous Fault Status Register. */
/*****************************************************************************/
/* SFSR register definition */
/* */
/* +----------------+---+---+------+---+---+---+-----+------+------+---+---+ */
/* | rsvd | CS| r | PERR | r | TO| BE| L | AT | FT |FAV| OW| */
/* +----------------+---+---+------+---+---+---+-----+------+------+---+---+ */
/* 31 17 16 15 14 13 12 11 10 09 08 07 05 04 02 01 00 */
/* */
/* sf_status definition */
/* +----------------+---+---+------+---+---+---+-----+------+------+---+---+ */
/* | | CS| | PERR | | TO| BE| L | AT | FT |FAV| OW| */
/* +----------------+---+---+------+---+---+---+-----+------+------+---+---+ */
/* 14 13 12 11 10 09 08 07 05 04 02 01 00 */
/* */
/*****************************************************************************/
/*** registered valid ASI bit ************************************************/
/*** Track valid ASI field with PARs. **********************************/
wire par_asi_vld_in
= ~mmu_asi_op ;
Mflipflop_r_1 par_asi_ff_1(par_asi_vld,par_asi_vld_in,~ss_reset,ss_clock) ;
/*** registered tlb_acc bits *************************************************/
/*** Track Access permission field with PARs. *************************/
wire ipar_acc_hld
= ipar_valid | ~ic_tlb ;
wire [2:0] tlb_acc
= mmu_bypass ? {3'b111} : tlb_acc_raw ;
wire [2:0] ipar_acc
;
MflipflopR_3 ipar_acc_ff_3(ipar_acc,tlb_acc,ss_clock,ipar_acc_hld,ss_reset) ;
wire dpar_acc_hld
= dpar_valid | ~dc_in_par ;
wire [2:0] dpar_acc
;
MflipflopR_3 dpar_acc_ff_3(dpar_acc,tlb_acc,ss_clock,dpar_acc_hld,ss_reset) ;
/*** Select ACC field from reg'd TLB, DPAR or IPAR values ********************/
wire [2:0] tlb_acc_in
= (ic_par_state | dc_par_state) ?
(dc_par_state ? dpar_acc : ipar_acc) : tlb_acc ;
wire [2:0] tlb_acc_x
;
Mflipflop_r_3 tlb_acc_ff_3(tlb_acc_x,tlb_acc_in,~ss_reset,ss_clock) ;
/*** Instruction access decode *****/
/*** All instruction accesses are assumed Supervisor. This is *****/
/*** for prefetching (since it can't be determined). *****/
wire [2:0] inst_acc_dcd
= 3'b011 ;
/*** the current access type needs to correspond with the current */
/*** translation op. The following equation set the access type */
/*** according to the operation. */
Mflipflop_r_3 data_acc_treg_3(data_acc_t,data_acc_s,~ss_reset,ss_clock) ;
assign at_t = data_op ? data_acc_t : inst_acc_dcd;
/*** Access type in the execute stage **********************************/
// r_data_op only gets used buy mux and comparator. -- sand
//wire r_data_op ;
//Mflipflop_r_1 data_op_reg_1(r_data_op,data_op,~ss_reset,ss_clock) ;
wire [2:0] data_acc_x
;
Mflipflop_r_3 data_accx_reg_3(data_acc_x,data_acc_t,~ss_reset,ss_clock) ;
// The mux and comparator now use the non-flopped versions of these
// signals. The outputs of the comparator are now flopped. Timming
// Fix --- Sand
//wire [2:0] at_x = r_data_op ? data_acc_x : inst_acc_dcd ;
wire [2:0] at_x
= data_op ? data_acc_t : inst_acc_dcd ;
// Change assign to un-flopped version -- sand
wire [2:0] af_x
= tlb_acc_in;
/*** No fault if PCR.nf = 1 and Supervisor access. *****************/
wire no_fault
= mmu_cr[1] & ~asi_dcd9_w;
/*** See Tsunami spec for Protection Error decode *****************/
wire prtct_err_dcd_n
= (((at_x == 3'h0) & (af_x == 3'h4)) |
((at_x == 3'h1) & (af_x == 3'h4)) |
((at_x == 3'h2) & ((af_x == 3'h0) | (af_x == 3'h1) |
(af_x == 3'h5))) |
((at_x == 3'h3) & ((af_x == 3'h0) | (af_x == 3'h1) |
(af_x == 3'h5))) |
((at_x == 3'h4) & ((af_x == 3'h0) | (af_x == 3'h2) |
(af_x == 3'h4) | (af_x == 3'h5))) |
((at_x == 3'h5) & ((af_x == 3'h0) | (af_x == 3'h2) |
(af_x == 3'h4) | (af_x == 3'h6))) |
((at_x == 3'h6) & ((af_x == 3'h0) | (af_x == 3'h1) |
(af_x == 3'h2) | (af_x == 3'h4) |
(af_x == 3'h5))) |
((at_x == 3'h7) & ((af_x == 3'h0) | (af_x == 3'h1) |
(af_x == 3'h2) | (af_x == 3'h4) |
(af_x == 3'h5) | (af_x == 3'h6))));
// Flopping the output of Comparator.
wire prtct_err_dcd
;
Mflipflop_r prtct_err_reg(prtct_err_dcd,prtct_err_dcd_n,~ss_reset,ss_clock) ;
//
wire enbl_err_t
= ~tlb_miss & ~io_op & ~tw_par &
~(data_op & iu_in_trap) &
((wr_tlb & ~wr_bypass) |
(~mmu_bypass & normal_asi_w & ~asi_dcd3));
wire enbl_err_x
;
Mflipflop_r_1 enbl_err_ff_1(enbl_err_x,enbl_err_t,~ss_reset,ss_clock) ;
assign prtct_err_x= prtct_err_dcd & enbl_err_x;
/*** The IO_PTE Write bit is the same as tlb_acc[0]. ********/
wire io_prtct_err
= (r_sxlate_ioreq & ~tlb_acc[0] & io_op &
~tlb_miss & ~io_mmu_bp & io_cr[0]);
/*** These regs are needed to determine when to look at ldd_w for parity **/
wire r_iwait_state
; //forward
wire r_ic_fill
;
wire ic_fill
= (r_iwait_state | r_ic_fill) ;
Mflipflop_r_1 r_ic_fill_ff_1(r_ic_fill,ic_fill,~ss_reset,ss_clock) ;
/*** Dcache parity errors are asynchronous errors (level-15 int) ***/
/*** An error is reported on if it is on the word returned. ***/
/*** The Dcache should always invalidate the corresponding $ line ***/
wire r_dccfstb
;
Mflipflop_r_1 mm_dccfstb_ff_1(r_dccfstb,mm_dccfstb,~ss_reset,ss_clock) ;
/*** Use chk_dpar (data cache parity) to delay strobes to match perr *****/
wire chk_dpar
= mop_c_bit ? (r_dccfstb & ~r_mstb_l) :
((r_dccfstb & ~r_mstb_l) & r_drd_c1) ;
wire msm_sreq
;
MflipflopR_1 msm_sreq_reg_1(msm_sreq,r_sb_par,ss_clock,~mem_issue_req,ss_reset) ;
wire r_odd_wd
;
Mflipflop_r_1 odd_wd_ff_1(r_odd_wd,odd_wd,~ss_reset,ss_clock) ;
/*** Qualified parity error bits for MFSR ********************************/
wire msm_wrt_cyc
;
MflipflopR_1 msm_wrt_cyc_ff_1(msm_wrt_cyc,mm_mreq[3], ss_clock,~mem_issue_req,ss_reset) ;
wire mf_perr
= ((msm_sreq |
(chk_dpar & (mop_c_bit | ldd_w))) & perr_dcd) |
((chk_dpar | msm_wrt_cyc | (ldtlb_data_tw & io_tlb_tw) |
(ldtlb_data_tw & wr_tlb_tw)) &
(odd_wd ? dp_perr[0] : dp_perr[1])) |
mc_afx_to ;
/*** Qualified parity error bits for SFSR ********************************/
/*** Only tablewalk parity (non-store hit) is loaded directly into ***/
/*** the SFSR. The I$ parity errors go through the IU. ***/
wire [1:0] data_sf_perr
= (sr_tw_wrt & dc_tlb_tw) ? r_perr : 2'b0 ;
wire [1:0] r_data_sf_perr
;
Mflipflop_r_2 r_d_sf_perr_ff_2(r_data_sf_perr,data_sf_perr,~ss_reset,ss_clock) ;
wire [1:0] sf_perr
= (|iu_sfs_perr) ? iu_sfs_perr : r_data_sf_perr ;
assign tw_perr = r_perr_dcd & (sr_tw_wrt | io_tw_wrt);
wire tlb_walk_perr
= sr_tw_wrt & (r_odd_wd ? r_perr[0] : r_perr[1]) ;
wire io_tlb_walk_perr
= io_tw_wrt & (r_odd_wd ? r_perr[0] : r_perr[1]) ;
wire r_io_tlb_walk_perr
;
MflipflopR_1 io_tlb_walk_perr_ff_1(r_io_tlb_walk_perr,io_tlb_walk_perr, ss_clock,1'b0,ss_reset) ;
/*** Need reg'd version to sync up with tablewalk level field decode *******/
wire r_tlb_walk_perr
;
MflipflopR_1 tlb_walk_perr_ff_1(r_tlb_walk_perr,tlb_walk_perr, ss_clock,1'b0,ss_reset) ;
/*** See spec for Privileged Error decode *****************/
wire priv_err_dcd_n
= (((at_x == 3'h0) | (at_x == 3'h2) |
(at_x == 3'h4) | (at_x == 3'h6)) &
((af_x == 3'h6) | (af_x == 3'h7)));
// Flopping the output of Comparator.
wire priv_err_dcd
;
Mflipflop_r priv_err_reg(priv_err_dcd,priv_err_dcd_n,~ss_reset,ss_clock) ;
//
assign priv_err_x = priv_err_dcd & enbl_err_x;
/*** Register err type to sync with reg'd sb_ioreq *************************/
wire [1:0] r_sb_errtype
;
Mflipflop_r_2 sb_errtype_ff_2(r_sb_errtype,~sb_err_type,~ss_reset,ss_clock) ;
wire [1:0] r_sb_err_type
= ~r_sb_errtype ;
/*** Access error on CPU read (D$ access) and an SBus err ************/
wire sb_dacc_err
= (~sb_wrt_err & ~r_sb_err_type[0] & ~r_sb_ic_op) ;
/*** decode separate access error signal for tablewalk checking. **********/
wire tw_priv_err
= tw_pte_chk & priv_err_dcd ;
wire tw_prtct_err
= tw_pte_chk & prtct_err_dcd ;
assign r_acc_err_tw = tw_priv_err | tw_prtct_err ;
/*** D-cache TLB privilege exception (t-stage +1) ********************/
wire r_dc_priv_err
= priv_err_x & r_dc_tlb & r_dc_miss &
((read_w & ~wb_valid_x) | st_miss_x) ;
/*** D-cache TLB protection exception (t-stage +1) ********************/
wire r_dc_prtct_err
= prtct_err_x & r_dc_tlb & r_dc_miss &
((read_w & ~wb_valid_x) | st_miss_x) ;
/*** Write-buffer TLB privilege OR protection exception (t-stage +1) *****/
wire wb_xlat_err
= ((priv_err_x | prtct_err_x) & r_wr_tlb & wb_valid_x) |
(wr_tlb_tw & (tw_priv_err | tw_prtct_err));
/*** Write buffer error - signal used to strobe the write buffer *********/
assign wb_err = wb_xlat_err | (wr_tlb_tw & (tw_addr_err | tw_xlat_err)) ;
wire soft_tw_miss
= iacc_miss | dacc_miss ;
/*********** Fault type decode function **********************************/
parameter [2:0] NO_FAULT = 3'b000,
INVALID_ADDR = 3'b001,
PROTECTION = 3'b010,
PRIVILEGE = 3'b011,
TRANSLATION = 3'b100,
ACCESS_BUS = 3'b101,
INTERNAL = 3'b110;
function [2:0] fault_dcd;
input tw_addr_err;
input tw_xlat_err;
input tw_priv_err;
input tw_prtct_err;
input r_dc_priv_err;
input r_dc_prtct_err;
input wb_xlat_err;
input sb_dacc_err;
input asi_err_cntl;
input mmu_en;
input r_tlb_walk_perr;
input dc_tlb_tw;
input wr_tlb_tw;
input dacc_miss; // Soft tablewalk miss -> translation error
input iu_sfs_sup; // IU fault status supervisor bit
input [1:0] iu_sfs_perr; // IU fault status Parity error
input iu_sfs_xerr; // IU fault status translation error
input iu_sfs_mmiss; // IU fault status TLB miss (software tw)
input iu_sfs_iae; // IU fault status Invalid Address Error
input iu_sfs_sbe; // IU fault status Sbus error
input iu_sfs_sto; // IU fault status Sbus timeout
input iu_sfs_prtct; // IU fault status protection exception
input iu_sfs_priv; // IU fault status privilege exception
input probe; // IU fault status privilege exception
/*** Internal Error decode *************************************************/
/*** Some internal state is out of sync (highest priority) ***/
/*** Translate error on wb tablewalk (can't be on store HIT) ***/
/*** Invalid Address error on wb tablewalk (can't be on store HIT) ***/
if (mmu_en & (wb_xlat_err |
(wr_tlb_tw & ((tw_xlat_err & ~r_tlb_walk_perr) | tw_addr_err))))
fault_dcd = INTERNAL ;
/*** Translation Error decode **********************************************/
/*** First 3 cases are D-cache translation errors ***/
/*** D-cache tablewalk translate error (ET = 3) ***/
/*** D-cache tablewalk parity error (not a write buffer tablewalk) ***/
/*** D-cache TLB miss when software tablewalks are enabled ***/
/*** 2 I-cache cases (Reported from W-stage of IU) ***/
/*** Instruction translate error (ET=3 or parity error on tw) ***/
/*** Instruction TLB miss when software tablewalks are enabled ***/
else if (mmu_en & ((dc_tlb_tw & tw_xlat_err ) | dacc_miss |
(probe & r_tlb_walk_perr)) | (iu_sfs_xerr | iu_sfs_mmiss))
fault_dcd = TRANSLATION ;
/*** Invalid Address Error decode ******************************************/
/*** D-cache tablewalk Invalid Address Error (ET=0) ***/
/*** Instruction tablewalk Invalid Address Error (ET=0) ***/
else if ((mmu_en & dc_tlb_tw & tw_addr_err) | iu_sfs_iae)
fault_dcd = INVALID_ADDR ;
/*** Privilege Exception Decode ********************************************/
/*** Privilege exception on D-cache translation or tablewalk ***/
/*** Instruction privilege exception from IU W-stage ***/
else if ((mmu_en & (r_dc_priv_err | (tw_priv_err & dc_tlb_tw))) |
iu_sfs_priv)
fault_dcd = PRIVILEGE ;
/*** Protection Exception Decode *******************************************/
/*** Protection exception on D-cache translation or tablewalk ***/
/*** Instruction Protection exception from IU W-stage ***/
else if ((mmu_en & (r_dc_prtct_err | (tw_prtct_err & dc_tlb_tw))) |
iu_sfs_prtct)
fault_dcd = PROTECTION ;
/*** Access Bus Error Decode ***********************************************/
/*** Sbus access error (bus error OR timeout) for D-cache ***/
/*** Control Space access error (illegal address or size) ***/
/*** Instruction access error (Sbus error OR timeout OR parity error) ***/
else if ((sb_dacc_err | asi_err_cntl) |
(iu_sfs_sbe | iu_sfs_sto | iu_sfs_perr[1] | iu_sfs_perr[0]))
fault_dcd = ACCESS_BUS ;
/*** No Fault **************************************************************/
else fault_dcd = NO_FAULT ;
endfunction
wire [2:0] fault_type
= fault_dcd (tw_addr_err, tw_xlat_err,
tw_priv_err, tw_prtct_err,
r_dc_priv_err, r_dc_prtct_err,
wb_xlat_err,
sb_dacc_err, asi_err_cntl, mmu_cr[0],
r_tlb_walk_perr,
dc_tlb_tw, wr_tlb_tw, dacc_miss,
iu_sfs_sup, iu_sfs_perr,
iu_sfs_xerr, iu_sfs_mmiss,
iu_sfs_iae, iu_sfs_sbe, iu_sfs_sto,
iu_sfs_prtct, iu_sfs_priv, probe );
/************************************************************************/
/*** Data error fault bit - indicates that error status from data op. ***/
Mflipflop_r_1 iwait_state_ff_1(r_iwait_state, iwait_state,~ss_reset,ss_clock) ;
assign tw_err = tw_xlat_err | tw_addr_err | (probe & r_tlb_walk_perr) ;
wire tw_err_in
= tw_err | r_tw_err;
rsflop tw_err_ff (r_tw_err,tw_err_in,ss_clock,1'b0,~tw_par, ss_reset);
wire data_err
= (~(fault_type == ACCESS_BUS) &
((r_dc_tlb & (prtct_err_x | priv_err_x)) |
(r_dc_tlb & r_tlb_miss & enbl_soft_tw) |
dmiss_for_m |
(dc_tlb_tw & tw_pte_chk & r_acc_err_tw) |
(data_op & tw_err))) |
((fault_type == ACCESS_BUS) &
(asi_err_cntl | sb_dacc_err |
~(iu_sfs_sbe | iu_sfs_sto |
iu_sfs_perr[1] | iu_sfs_perr[0]))) ;
/***************************************************************************/
/*** Instruction Excpetion and Error decode logic *****/
/*** This does not set fault status, just signals IU of fault type *****/
/*** and fault status. *****/
/***************************************************************************/
/*** Decode for raw TLB level bits from RAM (tb_out[27:25]) *********/
/*** ***/
/*** tlb_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 ***/
wire [1:0] tlb_lvl_dcd
= {tlb_lvl[1],
((tlb_lvl[2] & ~tlb_lvl[1]) | tlb_lvl[0])} ;
/***************************************************************************/
/*** Decode for raw TLB level bits from tablewalk state machine ***********/
/*** ***/
/*** tw_wm_lvl[1:0] tlb_lvl_dcd[1:0] (PTE level) ***/
/*** ------------ ---------------- ----------- ***/
/*** 00 11 level-3 ***/
/*** 01 00 level-0 ***/
/*** 10 01 level-1 ***/
/*** 11 10 level-2 ***/
wire [1:0] tw_err_dcd
= {~(tw_err_lvl[1] ^ tw_err_lvl[0]),
~tw_err_lvl[0]};
/***************************************************************************/
/*** Register TLB level to track with PAR (since used by caches on ***/
/*** mm_istat_avail or mm_dstat_avail - caches latch level status). ***/
wire [1:0] par_lvl
;
MflipflopR_2 par_lvl_ff_2(par_lvl,tlb_lvl_dcd,ss_clock,hold_par,ss_reset) ;
wire [1:0] ipar_lvl
;
MflipflopR_2 ipar_lvl_ff_2(ipar_lvl,tlb_lvl_dcd,ss_clock,ipar_valid,ss_reset) ;
/*** Pipe par_lvl 1-cycle to match mm_istat_avail strobe *******************/
wire [1:0] r_par_lvl_in
= ic_par_state ? ipar_lvl : par_lvl ;
wire [1:0] r_par_lvl
;
Mflipflop_r_2 r_par_lvl_ff_2(r_par_lvl,r_par_lvl_in,~ss_reset,ss_clock) ;
/***************************************************************************/
/*** Select fault status level based on tablewalk active status. ***/
wire [1:0] r_tlb_lvl
; // forward
assign mm_fs_lvl = mm_iabort ? (r_tw_err ? tw_err_dcd : r_tlb_lvl)
: r_par_lvl ;
/***************************************************************************/
/*** Instruction Invalid Adddress Exception *****/
/*** NOTE lvl hold signal is one cycle late so we OR hld_in and hld *****/
/*** This may result in a TIMING Problem *****/
/*** Set registered bit on decoded error OR *****/
/*** I-cache watchpoint trap detected *****/
/*** Hold on 'iu_pipe_hold' OR ~hold_fetch_f_l (see BUG #589) *****/
wire fs_iae_hld_in
= ((iu_pipe_hold | ~hold_fetch_f_l) & (mm_fs_iae |
(trig_a_term & (wp_trap_en | enbl_scan_bp) &
(mmu_brkpt_en[0] & (va_src_sel == 2'b00))))) |
(trig_a_term & (wp_trap_en | enbl_scan_bp) &
(mmu_brkpt_en[0] & (va_src_sel == 2'b00))) ;
wire mm_fs_iae_hld_r
;
Mflipflop_r_1 fs_iae_hld_ff_1(mm_fs_iae_hld_r,fs_iae_hld_in,~ss_reset,ss_clock) ;
assign mm_fs_iae = (ic_tlb_tw & tw_addr_err) | mm_fs_iae_hld_r ;
/***************************************************************************/
/*** Instruction translation error *****/
/*** Hold on 'iu_pipe_hold' OR ~hold_fetch_f_l (see BUG #589) *****/
wire fs_xerr_hld_in
= mm_fs_xerr & (iu_pipe_hold | ~hold_fetch_f_l) ;
wire mm_fs_xerr_hld
;
Mflipflop_r_1 fs_xerr_hld_ff_1(mm_fs_xerr_hld,fs_xerr_hld_in,~ss_reset,ss_clock) ;
assign mm_fs_xerr = (ic_tlb_tw & tw_xlat_err) | mm_fs_xerr_hld ;
/***************************************************************************/
/*** Instruction tablewalk parity exception *****/
/*** Hold on 'iu_pipe_hold' OR ~hold_fetch_f_l (see BUG #589) *****/
wire mm_fs_perr_hld
= ~((ic_tlb_tw & r_ic_miss & tlb_walk_perr) |
~(iu_pipe_hold | ~hold_fetch_f_l)) ;
wire [1:0] r_fs_perr
;
MflipflopR_2 fs_perr_ff_2(r_fs_perr,r_perr,ss_clock,mm_fs_perr_hld,ss_reset) ;
assign mm_fs_perr = {(r_perr[1] | r_fs_perr[1]),
(r_perr[0] | r_fs_perr[0])};
/***************************************************************************/
/***************************************************************************/
/*** Instruction protection exception *****/
/*** Set registered bit on decoded error OR *****/
/*** I-cache watchpoint trap detected *****/
/*** Hold on 'iu_pipe_hold' OR ~hold_fetch_f_l (see BUG #589) *****/
wire fs_sptct_hld_in
= ((iu_pipe_hold | ~hold_fetch_f_l) & (mm_fs_sptct |
(trig_a_term & (wp_trap_en | enbl_scan_bp) &
(mmu_brkpt_en[0] & (va_src_sel == 2'b00))))) |
(trig_a_term & (wp_trap_en | enbl_scan_bp) &
(mmu_brkpt_en[0] & (va_src_sel == 2'b00))) ;
wire mm_fs_sptct_hld
;
Mflipflop_r_1 fs_sptct_hld_ff_1(mm_fs_sptct_hld,fs_sptct_hld_in,~ss_reset,ss_clock) ;
assign mm_fs_sptct = (r_ic_tlb & r_ic_miss & prtct_err_x) |
(ic_tlb_tw & r_acc_err_tw) | mm_fs_sptct_hld ;
/*** note: used r_acc_err_tw even though it includes priv_err checking *****/
/*** this should never happen for an instruction translation. *****/
/***************************************************************************/
/***************************************************************************/
/*** Instruction TLB miss with software tablewalks enabled *****/
/*** Hold on 'iu_pipe_hold' OR ~hold_fetch_f_l (see BUG #589) *****/
wire iacc_miss_in
= mm_fs_mmiss & (iu_pipe_hold | ~hold_fetch_f_l) ;
wire iacc_miss_hld
;
Mflipflop_r_1 iacc_miss_hld_ff_1(iacc_miss_hld,iacc_miss_in,~ss_reset,ss_clock) ;
assign mm_fs_mmiss = ((r_ic_tlb & r_tlb_miss & r_ic_miss & enbl_soft_tw) |
iacc_miss_hld) ;
assign iacc_miss = r_ic_tlb & r_tlb_miss & r_ic_miss & enbl_soft_tw ;
/***************************************************************************/
/*** Instruction Sbus bus error (access error) on fetch from I/O space *****/
/*** Hold on 'iu_pipe_hold' *****/
/*** ***/
/*** sb_err_type | Error type ***/
/*** -------------+--------------------------- ***/
/*** 00 | Sbus time out ***/
/*** 01 | Sbus late error ***/
/*** 10 | Sbus bus error (error acknowledge) ***/
/*** 11 | No Error ***/
wire sb_cp_to
= ~r_sb_err_type[1] & ~r_sb_err_type[0];
wire sb_cp_le
= ~r_sb_err_type[1] & r_sb_err_type[0];
wire sb_cp_be
= r_sb_err_type[1] & ~r_sb_err_type[0];
wire fs_sbe_hld_in
= mm_fs_sbe & (iu_pipe_hold | ~hold_fetch_f_l) ;
wire mm_fs_sbe_hld
;
Mflipflop_r_1 fs_sbe_hld_ff_1(mm_fs_sbe_hld,fs_sbe_hld_in,~ss_reset,ss_clock) ;
assign mm_fs_sbe = (r_sb_ic_op & sb_cp_be) | mm_fs_sbe_hld ;
/***************************************************************************/
/*** Instruction Sbus timeout (access error) on fetch from I/O space *****/
wire fs_sto_hld_in
= mm_fs_sto & (iu_pipe_hold | ~hold_fetch_f_l) ;
wire mm_fs_sto_hld
;
Mflipflop_r_1 fs_sto_hld_ff_1(mm_fs_sto_hld,fs_sto_hld_in,~ss_reset,ss_clock) ;
assign mm_fs_sto = (r_sb_ic_op & sb_cp_to) | mm_fs_sto_hld ;
/***************************************************************************/
/***************************************************************************/
wire hold_sfsr
;
wire r_data_err
;
rsflop data_err_ff (r_data_err,data_err,
ss_clock,hold_sfsr,rd_sfsr,ss_reset);
wire [2:0] sfsr_ft
;
wire ld_sfsr
;
wire ow_in
;
/* */
/***************************************************************************/
/******** Fault priority decoding - (ld_sfsr and OW bit) *******************/
/*** ***/
/*** fault_priority reflects the 2 bits indicating ***/
/*** ld_sfsr - SFSR load enable ***/
/*** ow - Overwrite bit ***/
function [1:0] fault_priority;
input [2:0] fault_type; /* current fault type */
input [2:0] sfsr_ft; /* SFSR fault type field */
input r_data_err;
input data_err;
case (fault_type) // synopsys parallel_case
INTERNAL: fault_priority = {2'b10};
TRANSLATION: if(sfsr_ft == INTERNAL)
fault_priority = {2'b00};
else if (sfsr_ft == TRANSLATION)
fault_priority = {2'b11};
else fault_priority = {2'b10};
INVALID_ADDR: if ((sfsr_ft == INTERNAL) | (sfsr_ft == TRANSLATION) |
(r_data_err & ~data_err & ~(sfsr_ft == NO_FAULT)))
fault_priority = {2'b00};
else if (~(r_data_err ^ data_err) & ~(sfsr_ft == NO_FAULT))
fault_priority = {2'b11};
else fault_priority = {2'b10};
PRIVILEGE: if ((sfsr_ft == INTERNAL) | (sfsr_ft == TRANSLATION) |
(r_data_err & ~data_err & ~(sfsr_ft == NO_FAULT)))
fault_priority = {2'b00};
else if (~(r_data_err ^ data_err) & ~(sfsr_ft == NO_FAULT))
fault_priority = {2'b11};
else fault_priority = {2'b10};
PROTECTION: if ((sfsr_ft == INTERNAL) | (sfsr_ft == TRANSLATION) |
(r_data_err & ~data_err & ~(sfsr_ft == NO_FAULT)))
fault_priority = {2'b00};
else if (~(r_data_err ^ data_err) & ~(sfsr_ft == NO_FAULT))
fault_priority = {2'b11};
else fault_priority = {2'b10};
ACCESS_BUS: if ((sfsr_ft == INTERNAL) | (sfsr_ft == TRANSLATION) |
(r_data_err & ~data_err & ~(sfsr_ft == NO_FAULT)))
fault_priority = {2'b00};
else if (~(r_data_err ^ data_err) & ~(sfsr_ft == NO_FAULT))
fault_priority = {2'b11};
else fault_priority = {2'b10};
default: fault_priority = {2'b00};
endcase
endfunction
assign {ld_sfsr,ow_in} = fault_priority(fault_type, sfsr_ft,
r_data_err, data_err);
/*****************************************************************************/
wire fav
= data_err; /* Fault Addr is valid for Data errors */
assign hold_sfsr = (hld_sfsr & ~ld_sfsr) | rd_sfsr ;
assign hold_sfar = hld_sfar & ~ld_sfsr;
/*****************************************************************************/
MflipflopR_2 r_tlb_lvl_ff_2(r_tlb_lvl,tlb_lvl_dcd,ss_clock,r_acc_err_tw,ss_reset) ;
wire [1:0] err_lvl
= tw_err ? tw_err_dcd : r_tlb_lvl ;
wire [1:0] sfsr_lvl
= (fault_type == 3'b101) ? 2'b0 :
(data_err ? err_lvl : iu_sfs_lvl) ;
wire [2:0] sfsr_at
= data_err ? data_acc_x : {2'b01, iu_sfs_sup} ;
wire sf_sb_to
= data_err ? sb_cp_to : iu_sfs_sto ;
wire sf_sb_be
= data_err ? sb_cp_be : iu_sfs_sbe ;
wire [14:00] sf_status
= {asi_err_cntl, /* control space error bit */
sf_perr[1:0], /* 2-bit data parity err field*/
sf_sb_to, /* SBus time-out*/
sf_sb_be, /* SBus error*/
sfsr_lvl, /* 2-bit level field from TLB*/
sfsr_at, /* 3-bit access type field*/
fault_type, /* 3-bit fault type field*/
fav, /* fault address valid*/
ow_in}; /* overwrite bit*/
wire [14:00] sfsr_data_in
= {misc_in[16],misc_in[14:13],
misc_in[11:00]};
wire [14:00] sfsr_in
;
// Expanded macro begin.
// cmux2(sfsr_mux, 15, sfsr_in, sfsr_data_in, sf_status, hld_sfsr)
function [15:1] sfsr_mux ;
input [15:1] in0_fn ;
input [15:1] in1_fn ;
input select_fn ;
reg [15: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
sfsr_mux = out_fn ;
end
endfunction
assign sfsr_in = sfsr_mux( sfsr_data_in, sf_status, hld_sfsr) ;
// Expanded macro end.
wire [14:00] sfsr
;
rsflop_sfsr sfsr_reg(sfsr,
sfsr_in, /* load PAR from the DATA Physical Address*/
ss_clock,hold_sfsr,
rd_sfsr,ss_reset); /* load enable for PAR*/
assign sfsr_ft = sfsr[4:2];
/************************************************************************/
/*** SFSR load monitor (displays when SFSR was loaded - for debug ***/
// synopsys translate_off
wire [31:00] sfsr_disp
= {15'b0, sfsr_in[14], 1'b0, sfsr_in[13:12],
1'b0, sfsr_in[11:00] } ;
always @(posedge ss_clock) begin
sfsr_display;
end
This page: |
Created: | Thu Aug 19 12:02:50 1999 |
| From: |
../../../sparc_v8/ssparc/mmu/m_mmu_cntl/rtl/rl_mmu_regs.v
|