Line 42... |
Line 42... |
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//
|
//
|
// CVS Revision History
|
// CVS Revision History
|
//
|
//
|
// $Log: not supported by cvs2svn $
|
// $Log: not supported by cvs2svn $
|
|
// Revision 1.7 2002/08/12 05:31:30 lampret
|
|
// Delayed external access at page crossing.
|
|
//
|
// Revision 1.6 2002/03/29 15:16:56 lampret
|
// Revision 1.6 2002/03/29 15:16:56 lampret
|
// Some of the warnings fixed.
|
// Some of the warnings fixed.
|
//
|
//
|
// Revision 1.5 2002/02/11 04:33:17 lampret
|
// Revision 1.5 2002/02/11 04:33:17 lampret
|
// Speed optimizations (removed duplicate _cyc_ and _stb_). Fixed D/IMMU cache-inhibit attr.
|
// Speed optimizations (removed duplicate _cyc_ and _stb_). Fixed D/IMMU cache-inhibit attr.
|
Line 168... |
Line 171... |
wire page_cross;
|
wire page_cross;
|
reg [31:0] icpu_adr_o;
|
reg [31:0] icpu_adr_o;
|
`ifdef OR1200_NO_IMMU
|
`ifdef OR1200_NO_IMMU
|
`else
|
`else
|
reg itlb_en_r;
|
reg itlb_en_r;
|
|
reg dis_spr_access;
|
reg [31:`OR1200_IMMU_PS] icpu_vpn_r;
|
reg [31:`OR1200_IMMU_PS] icpu_vpn_r;
|
`endif
|
`endif
|
|
|
//
|
//
|
// Implemented bits inside match and translate registers
|
// Implemented bits inside match and translate registers
|
Line 221... |
Line 225... |
// 1200 - 123F itlbmr w0 [63:0]
|
// 1200 - 123F itlbmr w0 [63:0]
|
//
|
//
|
// 1300 - 13FF itlbtr w0
|
// 1300 - 13FF itlbtr w0
|
// 1300 - 133F itlbtr w0 [63:0]
|
// 1300 - 133F itlbtr w0 [63:0]
|
//
|
//
|
assign itlb_spr_access = spr_cs;
|
assign itlb_spr_access = spr_cs & ~dis_spr_access;
|
|
|
|
//
|
|
// Disable ITLB SPR access
|
|
//
|
|
// This flop is used to mask ITLB miss/fault exception
|
|
// during first clock cycle of accessing ITLB SPR. In
|
|
// subsequent clock cycles it is assumed that ITLB SPR
|
|
// access was accomplished and that normal instruction fetching
|
|
// can proceed.
|
|
//
|
|
// spr_cs sets dis_spr_access and icpu_rty_o clears it.
|
|
//
|
|
always @(posedge clk or posedge rst)
|
|
if (rst)
|
|
dis_spr_access <= #1 1'b0;
|
|
else if (!icpu_rty_o)
|
|
dis_spr_access <= #1 1'b0;
|
|
else if (spr_cs)
|
|
dis_spr_access <= #1 1'b1;
|
|
|
//
|
//
|
// Tags:
|
// Tags:
|
//
|
//
|
// OR1200_DTAG_TE - TLB miss Exception
|
// OR1200_DTAG_TE - TLB miss Exception
|
Line 235... |
Line 258... |
|
|
//
|
//
|
// icpu_rty_o
|
// icpu_rty_o
|
//
|
//
|
// assign icpu_rty_o = !icpu_err_o & icimmu_rty_i;
|
// assign icpu_rty_o = !icpu_err_o & icimmu_rty_i;
|
assign icpu_rty_o = icimmu_rty_i;
|
assign icpu_rty_o = icimmu_rty_i | itlb_spr_access;
|
|
|
//
|
//
|
// icpu_err_o
|
// icpu_err_o
|
//
|
//
|
assign icpu_err_o = miss | fault | icimmu_err_i;
|
assign icpu_err_o = miss | fault | icimmu_err_i;
|
|
|
//
|
//
|
// Assert itlb_en_r after one clock cycle
|
// Assert itlb_en_r after one clock cycle and when there is no
|
|
// ITLB SPR access
|
//
|
//
|
always @(posedge clk or posedge rst)
|
always @(posedge clk or posedge rst)
|
if (rst)
|
if (rst)
|
itlb_en_r <= #1 1'b0;
|
itlb_en_r <= #1 1'b0;
|
else
|
else
|
itlb_en_r <= #1 itlb_en;
|
itlb_en_r <= #1 itlb_en & ~itlb_spr_access;
|
|
|
//
|
//
|
// Assert itlb_done one clock cycle after new address is first presented and tlb is enabled.
|
// ITLB lookup successful
|
//
|
//
|
// assign itlb_done = (icpu_adr_i == icpu_adr_o) & itlb_en_r;
|
assign itlb_done = itlb_en_r & ~page_cross;
|
assign itlb_done = itlb_en_r;
|
|
|
|
//
|
//
|
// Cut transfer if something goes wrong with translation. If IC is disabled,
|
// Cut transfer if something goes wrong with translation. If IC is disabled,
|
// use delayed signals.
|
// use delayed signals.
|
//
|
//
|
Line 273... |
Line 296... |
//
|
//
|
// Page cross
|
// Page cross
|
//
|
//
|
// Asserted when CPU address crosses page boundary. Most of the time it is zero.
|
// Asserted when CPU address crosses page boundary. Most of the time it is zero.
|
//
|
//
|
assign page_cross = icpu_adr_i[31:`OR1200_IMMU_PS] != icimmu_adr_o[31:`OR1200_IMMU_PS];
|
assign page_cross = icpu_adr_i[31:`OR1200_IMMU_PS] != icpu_vpn_r;
|
|
|
//
|
//
|
// Register icpu_adr_i's VPN for use when IMMU is not enabled but PPN is expected to come
|
// Register icpu_adr_i's VPN for use when IMMU is not enabled but PPN is expected to come
|
// one clock cycle after offset part.
|
// one clock cycle after offset part.
|
//
|
//
|
Line 294... |
Line 317... |
assign icimmu_adr_o = immu_en ? {itlb_ppn, icpu_adr_i[`OR1200_IMMU_PS-1:0]} : {icpu_vpn_r, icpu_adr_i[`OR1200_IMMU_PS-1:0]};
|
assign icimmu_adr_o = immu_en ? {itlb_ppn, icpu_adr_i[`OR1200_IMMU_PS-1:0]} : {icpu_vpn_r, icpu_adr_i[`OR1200_IMMU_PS-1:0]};
|
|
|
//
|
//
|
// Output to SPRS unit
|
// Output to SPRS unit
|
//
|
//
|
assign spr_dat_o = itlb_spr_access ? itlb_dat_o : 32'h00000000;
|
assign spr_dat_o = spr_cs ? itlb_dat_o : 32'h00000000;
|
|
|
//
|
//
|
// Page fault exception logic
|
// Page fault exception logic
|
//
|
//
|
assign fault = itlb_done &
|
assign fault = itlb_done &
|